Usando JavaScript para exibir um Blob

88

Estou recuperando uma imagem Blob de um banco de dados e gostaria de poder visualizar essa imagem usando JavaScript. O código a seguir produz um ícone de imagem quebrado na página:

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

Aqui está um jsFiddle contendo todo o código necessário, incluindo o blob. O código completo deve exibir uma imagem corretamente.

GAgnew
fonte
Qual é o formato do blob? É uma imagem em algum formato (jpeg, png, gif etc.) ou apenas bytes RGB?
bjornd,
4
Não deveria ser em document.createElement('img');vez dedocument.createElement('image');?
Pablo Lozano

Respostas:

114

Você também pode obter o objeto BLOB diretamente de XMLHttpRequest. Definir responseType como blob resolve o problema. Aqui está o meu código:

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

E a função de resposta é parecida com esta:

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

Só precisamos criar um elemento de imagem vazio em HTML:

<img id="image"/>
AdamZ
fonte
22
A linha importante é a urlCreator.createObjectURL(blob)que retorna um imageUrl que pode ser atribuído a um src de imagem.
Agent47DarkSoul
7
Não se esqueça de revogar o URL criado assim que terminar de chamá-lo; revokeObjectURL
Ralpharoo
Eu diria que a imagem do OP está em algum tipo de campo em um banco de dados, ou seja, o OP não pode obtê-lo diretamente . Se ele pudesse fazer isso, provavelmente usaria uma img- tag diretamente em vez de fazer XHR / fetch; porque ambos são propensos a SOP.
Christian Ulbrich
75

Se você quiser usar fetch em seu 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;
});

Fonte:

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

Ogglas
fonte
Isso converterá automaticamente base64, já que a imagem é codificada em base64?
P Satish Patro
2
Eu te amo .. passei 4 horas tentando resolver até que encontrei isso.
tinyCoder
O que aconteceif (typeof URL !== "function") {}
zanderwar
19

Você pode converter sua string em um Uint8Array para obter os dados brutos. Em seguida, crie um Blob para esses dados e passe para URL.createObjectURL (blob) para converter o Blob em um URL que você passa para 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);

Você pode tentar o exemplo completo em: http://jsfiddle.net/nj82y73d/

nkron
fonte
14

Em seu exemplo, você deve createElement('img').

Em seu link base64blob != Base64.encode(blob),.

Isso funciona, contanto que seus dados sejam válidos http://jsfiddle.net/SXFwP/ (eu não tinha nenhuma imagem BMP, então tive que usar PNG).

Nachito
fonte
Bom ponto no img. Você deve notar que 'img' é um elemento de imagem html onde 'imagem' é um elemento de entrada html do tipo imagem, embora neste caso não faça diferença. Estou assumindo que os dados da imagem são válidos, pois vêm de uma fonte de terceiros. Você sabe como testar isso? Ou um site fácil que dá blob de imagem carregada? Eu gostaria de testar BMP's
GAgnew 04/10/2011
O "blob" em seu violino não é realmente um Blob. Você usou uma string codificada em base64.
elliotwesoff
5

Acho que ocorreu um erro no código embutido da sua imagem. Experimente isto:

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);

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

marius_neo
fonte
3

O problema era que eu tinha dados hexadecimais que precisavam ser convertidos em binários antes de serem codificados em base64.

em PHP:

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

No violino, seu blob não é um blob, é uma representação em string de dados hexadecimais. Experimente isso em um blob e pronto

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 fornece uma imagem codificada em base64 pronta para sua fonte de elemento de imagem () (src)

Bruno
fonte