Usar JavaScript para mostrar un blob

88

Estoy recuperando una imagen de Blob de una base de datos y me gustaría poder ver esa imagen usando JavaScript. El siguiente código produce un icono de imagen rota en la página:

var image = document.createElement('image');
    image.src = 'data:image/bmp;base64,'+Base64.encode(blob);
    document.body.appendChild(image);

Aquí hay un jsFiddle que contiene todo el código requerido, incluido el blob. El código completo debe mostrar correctamente una imagen.

GAgnew
fuente
¿Cuál es el formato del blob? ¿Es esta una imagen en algún formato (jpeg, png, gif, etc.) o solo bytes RGB?
bjornd
4
No debería ser en document.createElement('img');lugar dedocument.createElement('image');?
Pablo Lozano

Respuestas:

114

También puede obtener el objeto BLOB directamente desde XMLHttpRequest. Establecer responseType en blob hace el truco. Aquí está mi código:

var xhr = new XMLHttpRequest();
xhr.open("GET", "http://localhost/image.jpg");
xhr.responseType = "blob";
xhr.onload = response;
xhr.send();

Y la función de respuesta se ve así:

function response(e) {
   var urlCreator = window.URL || window.webkitURL;
   var imageUrl = urlCreator.createObjectURL(this.response);
   document.querySelector("#image").src = imageUrl;
}

Solo tenemos que hacer un elemento de imagen vacío en HTML:

<img id="image"/>
AdamZ
fuente
22
La línea importante es la urlCreator.createObjectURL(blob)que devuelve una imageUrl que se puede asignar a una imagen src.
Agent47DarkSoul
7
No olvide revocar la URL creada una vez que haya terminado llamando; revokeObjectURL
Ralpharoo
Supongo que la imagen de OP está en algún tipo de campo en una base de datos, es decir, OP no puede obtenerla directamente . Si pudiera hacerlo, probablemente usaría una imgetiqueta - directamente en lugar de hacer XHR / fetch; porque ambos son propensos a SOP.
Christian Ulbrich
75

Si desea utilizar fetch en su lugar:

var myImage = document.querySelector('img');

fetch('flowers.jpg').then(function(response) {
  return response.blob();
}).then(function(myBlob) {
  var objectURL = URL.createObjectURL(myBlob);
  myImage.src = objectURL;
});

Fuente:

https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch

Ogglas
fuente
¿Esto convertirá automáticamente base64 cuando la imagen esté codificada en base64?
P Satish Patro
2
Te amo ... pasé 4 horas tratando de resolver hasta que encontré esto.
tinyCoder
Que sucedeif (typeof URL !== "function") {}
zanderwar
19

Puede convertir su cadena en un Uint8Array para obtener los datos sin procesar. Luego, cree un Blob para esos datos y páselo a URL.createObjectURL (blob) para convertir el Blob en una URL que pase a img.src .

var data = '424D5E070000000000003E00000028000000EF...';

// Convert the string to bytes
var bytes = new Uint8Array(data.length / 2);

for (var i = 0; i < data.length; i += 2) {
    bytes[i / 2] = parseInt(data.substring(i, i + 2), /* base = */ 16);
}

// Make a Blob from the bytes
var blob = new Blob([bytes], {type: 'image/bmp'});

// Use createObjectURL to make a URL for the blob
var image = new Image();
image.src = URL.createObjectURL(blob);
document.body.appendChild(image);

Puede probar el ejemplo completo en: http://jsfiddle.net/nj82y73d/

nkron
fuente
14

En tu ejemplo, deberías createElement('img').

En su enlace, base64blob != Base64.encode(blob).

Esto funciona, siempre que sus datos sean válidos http://jsfiddle.net/SXFwP/ (no tenía ninguna imagen BMP, así que tuve que usar PNG).

nachito
fuente
Buen punto en la img. Debe tener en cuenta que 'img' es un elemento de imagen html donde 'imagen' es un elemento de entrada html de tipo imagen, aunque en este caso no hizo una diferencia. Supongo que los datos de la imagen son válidos, ya que provienen de una fuente de terceros. ¿Sabes de todos modos probar esto? ¿O un sitio fácil que da blob a partir de la imagen cargada? Me gustaría probar BMP's
GAgnew
La "mancha" en tu violín no es realmente una mancha. Usó una cadena codificada en base64.
elliotwesoff
5

Supongo que tuvo un error en el código en línea de su imagen. Prueba esto :

var image = document.createElement('img');
    
image.src="data:image/gif;base64,R0lGODlhDwAPAKECAAAAzMzM/////wAAACwAAAAADwAPAAACIISPeQHsrZ5ModrLlN48CXF8m2iQ3YmmKqVlRtW4MLwWACH+H09wdGltaXplZCBieSBVbGVhZCBTbWFydFNhdmVyIQAAOw==";
    
image.width=100;
image.height=100;
image.alt="here should be some image";
    
document.body.appendChild(image);

Enlace útil: http://dean.edwards.name/my/base64-ie.html

marius_neo
fuente
3

El problema era que tenía datos hexadecimales que debían convertirse a binarios antes de codificarlos en base64.

en PHP:

base64_encode(pack("H*", $subvalue))
GAgnew
fuente
0

En el violín, su blob no es un blob, es una representación de cadena de datos hexadecimales. Prueba esto en un blob y listo

var image = document.createElement('img');
let reader=new FileReader()
reader.addEventListener('loadend',()=>{
  let contents=reader.result
  image.src = contents
  document.body.appendChild(image);
})
if(blob instanceof Blob) reader.readAsDataURL(blob)

readAsDataURL le brinda una imagen codificada en base64 lista para su elemento de imagen () fuente (src)

Bruno
fuente