imagen funciona decodificar como codificacion btoa atob javascript base64

funciona - Creando un Blob desde una cadena base64 en JavaScript



decodificar base64 javascript (8)

La función que se describe a continuación está disponible en NPM : var b64toBlob = require(''b64-to-blob'')

La función atob decodificará una cadena codificada en base64 en una nueva cadena con un carácter para cada byte de los datos binarios.

var byteCharacters = atob(b64Data);

El punto de código de cada carácter (charCode) será el valor del byte. Podemos crear una matriz de valores de byte aplicando esto usando el método .charCodeAt para cada carácter en la cadena.

var byteNumbers = new Array(byteCharacters.length); for (var i = 0; i < byteCharacters.length; i++) { byteNumbers[i] = byteCharacters.charCodeAt(i); }

Puede convertir esta matriz de valores de bytes en una matriz de bytes de tipo real pasándola al constructor Uint8Array .

var byteArray = new Uint8Array(byteNumbers);

Esto a su vez se puede convertir en un Blob envolviéndolo en una matriz que pasa al constructor de Blob .

var blob = new Blob([byteArray], {type: contentType});

El código de arriba funciona. Sin embargo, el rendimiento puede mejorarse un poco al procesar los byteCharacters en segmentos más pequeños, en lugar de todos a la vez. En mis pruebas aproximadas, 512 bytes parece ser un buen tamaño de segmento. Esto nos da la siguiente función.

function b64toBlob(b64Data, contentType, sliceSize) { contentType = contentType || ''''; sliceSize = sliceSize || 512; var byteCharacters = atob(b64Data); var byteArrays = []; for (var offset = 0; offset < byteCharacters.length; offset += sliceSize) { var slice = byteCharacters.slice(offset, offset + sliceSize); var byteNumbers = new Array(slice.length); for (var i = 0; i < slice.length; i++) { byteNumbers[i] = slice.charCodeAt(i); } var byteArray = new Uint8Array(byteNumbers); byteArrays.push(byteArray); } var blob = new Blob(byteArrays, {type: contentType}); return blob; }

var blob = b64toBlob(b64Data, contentType); var blobUrl = URL.createObjectURL(blob); window.location = blobUrl;

Ejemplo completo:

function b64toBlob(b64Data, contentType, sliceSize) { contentType = contentType || ''''; sliceSize = sliceSize || 512; var byteCharacters = atob(b64Data); var byteArrays = []; for (var offset = 0; offset < byteCharacters.length; offset += sliceSize) { var slice = byteCharacters.slice(offset, offset + sliceSize); var byteNumbers = new Array(slice.length); for (var i = 0; i < slice.length; i++) { byteNumbers[i] = slice.charCodeAt(i); } var byteArray = new Uint8Array(byteNumbers); byteArrays.push(byteArray); } var blob = new Blob(byteArrays, {type: contentType}); return blob; } var contentType = ''image/png''; var b64Data = ''iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==''; var blob = b64toBlob(b64Data, contentType); var blobUrl = URL.createObjectURL(blob); var img = document.createElement(''img''); img.src = blobUrl; document.body.appendChild(img);

... o ES6:

''use strict''; const b64toBlob = (b64Data, contentType='''', sliceSize=512) => { const byteCharacters = atob(b64Data); const byteArrays = []; for (let offset = 0; offset < byteCharacters.length; offset += sliceSize) { const slice = byteCharacters.slice(offset, offset + sliceSize); const byteNumbers = new Array(slice.length); for (let i = 0; i < slice.length; i++) { byteNumbers[i] = slice.charCodeAt(i); } const byteArray = new Uint8Array(byteNumbers); byteArrays.push(byteArray); } const blob = new Blob(byteArrays, {type: contentType}); return blob; } const contentType = ''image/png''; const b64Data = ''iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==''; const blob = b64toBlob(b64Data, contentType); const blobUrl = URL.createObjectURL(blob); const img = document.createElement(''img''); img.src = blobUrl; document.body.appendChild(img);

Tengo datos binarios codificados en base64 en una cadena.

var contentType = ''image/png''; var b64Data = ''iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg=='';

Me gustaría crear un blob: URL que contenga estos datos y mostrarlos al usuario.

var blob = new Blob(????, {type: contentType}); var blobUrl = URL.createObjectURL(blob); window.location = blobUrl;

No he podido averiguar cómo crear el Blob .

En algunos casos, puedo evitar esto utilizando un data: URL en su lugar.

var dataUrl = ''data:'' + contentType + '';base64,'' + b64Data; window.location = dataUrl;

Sin embargo, en la mayoría de los casos, los data: URL son prohibitivamente grandes.

¿Cómo puedo decodificar una cadena base64 a un objeto Blob en JavaScript?


Implementación optimizada (pero menos legible):

function base64toBlob(base64Data, contentType) { contentType = contentType || ''''; var sliceSize = 1024; var byteCharacters = atob(base64Data); var bytesLength = byteCharacters.length; var slicesCount = Math.ceil(bytesLength / sliceSize); var byteArrays = new Array(slicesCount); for (var sliceIndex = 0; sliceIndex < slicesCount; ++sliceIndex) { var begin = sliceIndex * sliceSize; var end = Math.min(begin + sliceSize, bytesLength); var bytes = new Array(end - begin); for (var offset = begin, i = 0; offset < end; ++i, ++offset) { bytes[i] = byteCharacters[offset].charCodeAt(0); } byteArrays[sliceIndex] = new Uint8Array(bytes); } return new Blob(byteArrays, { type: contentType }); }


Me di cuenta de que Internet Explorer 11 se vuelve increíblemente lento al cortar los datos como sugirió Jeremy. Esto es cierto para Chrome, pero IE parece tener un problema al pasar los datos cortados al Blob-Constructor. En mi máquina, pasar 5 MB de datos hace que IE se bloquee y el consumo de memoria está por las nubes. Chrome crea la burbuja en ningún momento.

Ejecute este código para un comparismo:

var byteArrays = [], megaBytes = 2, byteArray = new Uint8Array(megaBytes*1024*1024), block, blobSlowOnIE, blobFastOnIE, i; for (i = 0; i < (megaBytes*1024); i++) { block = new Uint8Array(1024); byteArrays.push(block); } //debugger; console.profile("No Slices"); blobSlowOnIE = new Blob(byteArrays, { type: ''text/plain'' }); console.profileEnd(); console.profile("Slices"); blobFastOnIE = new Blob([byteArray], { type: ''text/plain'' }); console.profileEnd();

Así que decidí incluir los dos métodos descritos por Jeremy en una función. Los créditos van a él por esto.

function base64toBlob(base64Data, contentType, sliceSize) { var byteCharacters, byteArray, byteNumbers, blobData, blob; contentType = contentType || ''''; byteCharacters = atob(base64Data); // Get blob data sliced or not blobData = sliceSize ? getBlobDataSliced() : getBlobDataAtOnce(); blob = new Blob(blobData, { type: contentType }); return blob; /* * Get blob data in one slice. * => Fast in IE on new Blob(...) */ function getBlobDataAtOnce() { byteNumbers = new Array(byteCharacters.length); for (var i = 0; i < byteCharacters.length; i++) { byteNumbers[i] = byteCharacters.charCodeAt(i); } byteArray = new Uint8Array(byteNumbers); return [byteArray]; } /* * Get blob data in multiple slices. * => Slow in IE on new Blob(...) */ function getBlobDataSliced() { var slice, byteArrays = []; for (var offset = 0; offset < byteCharacters.length; offset += sliceSize) { slice = byteCharacters.slice(offset, offset + sliceSize); byteNumbers = new Array(slice.length); for (var i = 0; i < slice.length; i++) { byteNumbers[i] = slice.charCodeAt(i); } byteArray = new Uint8Array(byteNumbers); // Add slice byteArrays.push(byteArray); } return byteArrays; } }


No se pudo evitar no publicar el método minimalista sin dependencias o bibliotecas.
Requiere la nueva API fetch. ¿Puedo usarlo?

var url = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==" fetch(url) .then(res => res.blob()) .then(blob => console.log(blob))

Con este método también puede obtener fácilmente arraybuffer, text y json

Hice una prueba de rendimiento simple para la versión es6 sync de Jeremy.
La versión de sincronización bloqueará la interfaz de usuario por un tiempo.

// get some dummy gradient image var img=function(){var a=document.createElement("canvas"),b=a.getContext("2d"),c=b.createLinearGradient(0,0,200,100);a.width=a.height=3000;c.addColorStop(0,"red");c.addColorStop(1,"blue");b.fillStyle=c;b.fillRect(0,0,a.width,a.height);return a.toDataURL()}(); async function perf() { const blob = await fetch(img).then(res => res.blob()) // turn it to a dataURI const url = img const b64Data = url.split('','')[1] // Jeremy Banks solution const b64toBlob = (b64Data, contentType = '''', sliceSize=512) => { const byteCharacters = atob(b64Data); const byteArrays = []; for (let offset = 0; offset < byteCharacters.length; offset += sliceSize) { const slice = byteCharacters.slice(offset, offset + sliceSize); const byteNumbers = new Array(slice.length); for (let i = 0; i < slice.length; i++) { byteNumbers[i] = slice.charCodeAt(i); } const byteArray = new Uint8Array(byteNumbers); byteArrays.push(byteArray); } const blob = new Blob(byteArrays, {type: contentType}); return blob; } // bench blocking method let i = 1000 console.time(''b64'') while (i--) { await b64toBlob(b64Data) } console.timeEnd(''b64'') // bench non blocking i = 1000 // so that the function is not reconstructed each time const toBlob = res => res.blob() console.time(''fetch'') while (i--) { await fetch(url).then(toBlob) } console.timeEnd(''fetch'') console.log(''done'') } perf()


Para los datos de imagen, me parece más sencillo usar canvas.toBlob (asíncrono)

function b64toBlob(b64, onsuccess, onerror) { var img = new Image(); img.onerror = onerror; img.onload = function onload() { var canvas = document.createElement(''canvas''); canvas.width = img.width; canvas.height = img.height; var ctx = canvas.getContext(''2d''); ctx.drawImage(img, 0, 0, canvas.width, canvas.height); canvas.toBlob(onsuccess); }; img.src = b64; } var base64Data = ''data:image/jpg;base64,/9j/4AAQSkZJRgABAQA...''; b64toBlob(base64Data, function(blob) { var url = window.URL.createObjectURL(blob); // do something with url }, function(error) { // handle error });


Para todo el soporte del navegador, especialmente en Android. Quizás puedas agregar esto

try{ blob = new Blob( byteArrays, {type : contentType}); } catch(e){ // TypeError old chrome and FF window.BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder || window.MozBlobBuilder || window.MSBlobBuilder; if(e.name == ''TypeError'' && window.BlobBuilder){ var bb = new BlobBuilder(); bb.append(byteArrays); blob = bb.getBlob(contentType); } else if(e.name == "InvalidStateError"){ // InvalidStateError (tested on FF13 WinXP) blob = new Blob(byteArrays, {type : contentType}); } else{ // We''re screwed, blob constructor unsupported entirely } }


Si puede soportar agregar una dependencia a su proyecto, existe el gran paquete blob-util npm que proporciona una función base64StringToBlob . Una vez agregado a tu package.json , puedes usarlo así:

import { base64StringToBlob } from ''blob-util''; const contentType = ''image/png''; const b64Data = ''iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==''; const blob = base64StringToBlob(b64Data, contentType); // Do whatever you need with your blob...


Vea este ejemplo: https://jsfiddle.net/pqhdce2L/

function b64toBlob(b64Data, contentType, sliceSize) { contentType = contentType || ''''; sliceSize = sliceSize || 512; var byteCharacters = atob(b64Data); var byteArrays = []; for (var offset = 0; offset < byteCharacters.length; offset += sliceSize) { var slice = byteCharacters.slice(offset, offset + sliceSize); var byteNumbers = new Array(slice.length); for (var i = 0; i < slice.length; i++) { byteNumbers[i] = slice.charCodeAt(i); } var byteArray = new Uint8Array(byteNumbers); byteArrays.push(byteArray); } var blob = new Blob(byteArrays, {type: contentType}); return blob; } var contentType = ''image/png''; var b64Data = Your Base64 encode; var blob = b64toBlob(b64Data, contentType); var blobUrl = URL.createObjectURL(blob); var img = document.createElement(''img''); img.src = blobUrl; document.body.appendChild(img);