Visualizza l’immagine dal BLOB usando javascript e websockets

Attualmente sto lavorando a un’applicazione WebSocket che sta visualizzando immagini inviate da un server C ++. Ho visto un paio di argomenti in giro ma non riesco a liberarmi di questo errore in Firefox:

Immagine corrotta o troncata: data: image / png; base64, [alcuni dati]

Ecco il codice Javascript che sto usando per visualizzare il mio blob:

socket.onmessage = function(msg) { var blob = msg.data; var reader = new FileReader(); reader.onloadend = function() { var string = reader.result; var buffer = Base64.encode(string); var data = "data:image/png;base64,"+buffer; var image = document.getElementById('image'); image.src = data; }; reader.readAsBinaryString(blob); } 

Sto usando l’immagine di un punto rosso che ho trovato su questo argomento: https://stackoverflow.com/a/4478878/1464608 E la class Base64 proviene da qui: https://stackoverflow.com/a/246813/ 1464608

Ma il risultato base64 che ottengo non corrisponde e Firefox mi recupera un errore dell’immagine corrotta.

So che questo non è molte informazioni ma non ho la minima idea di dove guardare: / Qualsiasi aiuto è più che benvenuto !!

Penso che la soluzione più pulita sarebbe quella di modificare l’encoder base64 per operare direttamente su un Uint8Array anziché su una stringa.

Importante: per questo devi impostare binaryType del socket Web su “arraybuffer”.

Il metodo onmessage dovrebbe assomigliare a questo:

 socket.onmessage = function(msg) { var arrayBuffer = msg.data; var bytes = new Uint8Array(arrayBuffer); var image = document.getElementById('image'); image.src = 'data:image/png;base64,'+encode(bytes); }; 

L’encoder convertito dovrebbe quindi apparire come questo (basato su https://stackoverflow.com/a/246813/1464608 ):

 // public method for encoding an Uint8Array to base64 function encode (input) { var keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; var output = ""; var chr1, chr2, chr3, enc1, enc2, enc3, enc4; var i = 0; while (i < input.length) { chr1 = input[i++]; chr2 = i < input.length ? input[i++] : Number.NaN; // Not sure if the index chr3 = i < input.length ? input[i++] : Number.NaN; // checks are needed here enc1 = chr1 >> 2; enc2 = ((chr1 & 3) << 4) | (chr2 >> 4); enc3 = ((chr2 & 15) << 2) | (chr3 >> 6); enc4 = chr3 & 63; if (isNaN(chr2)) { enc3 = enc4 = 64; } else if (isNaN(chr3)) { enc4 = 64; } output += keyStr.charAt(enc1) + keyStr.charAt(enc2) + keyStr.charAt(enc3) + keyStr.charAt(enc4); } return output; } 

Grazie, sta funzionando alla grande !!

Quindi immagino di condividere il mio codice javascript finale:

 var socket = new WebSocket('ws://'+host+':'+port, protocol); socket.binaryType = 'arraybuffer'; try { socket.onopen = function() { document.getElementById('status').style.backgroundColor = '#40ff40'; document.getElementById('status').textContent = 'Connection opened'; } socket.onmessage = function(msg) { var arrayBuffer = msg.data; var bytes = new Uint8Array(arrayBuffer); var image = document.getElementById('image'); image.src = 'data:image/png;base64,'+encode(bytes); } socket.onclose = function(){ document.getElementById('status').style.backgroundColor = '#ff4040'; document.getElementById('status').textContent = 'Connection closed'; } } catch(exception) { alert('Error:'+exception); } 

non capisco davvero perché la versione blob sia così complicata ma questo ha fatto il trucco!

Puoi scriverlo in modo molto più semplice:

 socket.onmessage = function(msg) { var arrayBuffer = msg.data; var bytes = new Uint8Array(arrayBuffer); var blob = new Blob([bytes.buffer]); var image = document.getElementById('image'); var reader = new FileReader(); reader.onload = function(e) { image.src = e.target.result; }; reader.readAsDataURL(blob); }; 

Grazie alle altre risposte, sono riuscito a ricevere un’immagine jpeg da websocket e visualizzarla in una nuova finestra:

 socket.binaryType = "arraybuffer"; socket.onmessage = function (msg) { var bytes = new Uint8Array(msg.data); var blob = new Blob([bytes.buffer]); window.open(URL.createObjectURL(blob),'Name','resizable=1'); }; 

Un’altra alternativa

 let urlObject; socket.onmessage = function(msg) { const arrayBuffer = msg.data; const image = document.getElementById('image'); if (urlObject) { URL.revokeObjectURL(urlObject) // only required if you do that multiple times } urlObject = URL.createObjectURL(new Blob([arrayBuffer])); image.src = urlObject; };