Używanie JavaScript do wyświetlania obiektu Blob

88

Pobieram obraz Bloba z bazy danych i chciałbym mieć możliwość wyświetlenia tego obrazu przy użyciu JavaScript. Poniższy kod tworzy ikonę uszkodzonego obrazu na stronie:

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

Oto plik jsFiddle zawierający cały wymagany kod, w tym obiekt blob. Wypełniony kod powinien poprawnie wyświetlać obraz.

GAgnew
źródło
Jaki jest format obiektu blob? Czy jest to obraz w jakimś formacie (jpeg, png, gif itp.) Czy tylko w bajtach RGB?
bjornd
4
Nie powinno być document.createElement('img');zamiastdocument.createElement('image');?
Pablo Lozano

Odpowiedzi:

114

Możesz również pobrać obiekt BLOB bezpośrednio z XMLHttpRequest. Ustawienie responseType na blob sprawia, że ​​sztuczka. Oto mój kod:

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

A funkcja odpowiedzi wygląda następująco:

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

Musimy po prostu zrobić pusty element obrazu w HTML:

<img id="image"/>
AdamZ
źródło
22
Ważną linią jest ta, urlCreator.createObjectURL(blob)która zwraca imageUrl, który można przypisać do źródła obrazu.
Agent47DarkSoul,
7
Nie zapomnij unieważnić utworzonego adresu URL po zakończeniu z nim przez wywołanie; revokeObjectURL
Ralpharoo
Zakładam, że obraz OP znajduje się w jakimś polu w bazie danych, tj. OP nie może go pobrać bezpośrednio . Gdyby mógł to zrobić, najprawdopodobniej użyłby bezpośrednioimg tagu - zamiast wykonywać XHR / fetch; ponieważ oba są podatne na SOP.
Christian Ulbrich
75

Jeśli zamiast tego chcesz użyć funkcji pobierania:

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

Źródło:

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

Ogglas
źródło
Czy to automatycznie skonwertuje base64, ponieważ obraz jest zakodowany w formacie base64?
P Satish Patro
2
Kocham cię .. Spędziłem 4 godziny próbując rozwiązać, zanim to znalazłem.
tinyCoder
Co się dziejeif (typeof URL !== "function") {}
zanderwar
19

Możesz przekonwertować swój ciąg na Uint8Array, aby uzyskać nieprzetworzone dane. Następnie utwórz obiekt Blob dla tych danych i przekaż go do adresu URL.createObjectURL (blob), aby przekonwertować obiekt Blob na adres URL przekazywany do 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);

Możesz wypróbować pełny przykład pod adresem: http://jsfiddle.net/nj82y73d/

nkron
źródło
14

W twoim przykładzie powinieneś createElement('img').

W linku, base64blob != Base64.encode(blob).

To działa, o ile twoje dane są prawidłowe http://jsfiddle.net/SXFwP/ (nie miałem żadnych obrazów BMP, więc musiałem użyć PNG).

nachito
źródło
Dobra uwaga na img. Należy zauważyć, że „img” jest elementem obrazu html, gdzie „image” jest elementem wejściowym html typu image, chociaż w tym przypadku nie miało to znaczenia. Zakładam, że dane obrazu prawidłowe, ponieważ pochodzą z zewnętrznego źródła. Czy w ogóle wiesz o testowaniu tego? Lub prostą witrynę, która wyświetla blob z przesłanego obrazu? Chciałbym przetestować BMP
GAgnew
„Kropla” w twoich skrzypcach nie jest w rzeczywistości kropką. Użyto ciągu zakodowanego algorytmem Base64.
elliotwesoff
5

Wydaje mi się, że wystąpił błąd w kodzie wbudowanym obrazu. Spróbuj tego :

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

Pomocny link: http://dean.edwards.name/my/base64-ie.html

marius_neo
źródło
3

Problem polegał na tym, że miałem dane szesnastkowe, które musiały zostać przekonwertowane na binarne przed zakodowaniem base64.

w PHP:

base64_encode(pack("H*", $subvalue))
GAgnew
źródło
0

Na skrzypcach twój obiekt blob nie jest blobem, jest ciągiem reprezentującym dane szesnastkowe. Wypróbuj to na kropli i gotowe

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 daje gotowy obraz zakodowany w standardzie base64 element () źródło (src)

Bruno
źródło