Convertir blob a base64

140

Este es un fragmento del código que quiero hacer Blobpara Base64encadenar:

Esta parte comentada funciona y cuando la URL generada por esto se establece en img src, muestra la imagen:

var blob = items[i].getAsFile();
//var URLObj = window.URL || window.webkitURL;
//var source = URLObj.createObjectURL(blob);
//console.log("image source=" + source);

var reader = new FileReader();
reader.onload = function(event){
console.log(event.target.result)
}; // data url!
var source = reader.readAsBinaryString(blob);

El problema es con el código inferior, la variable fuente generada es nula

Actualizar:

¿Hay una manera más fácil de hacer esto con JQuery para poder crear una cadena Base64 a partir del archivo Blob como en el código anterior?

quarks
fuente

Respuestas:

273
 var reader = new FileReader();
 reader.readAsDataURL(blob); 
 reader.onloadend = function() {
     var base64data = reader.result;                
     console.log(base64data);
 }

Forma los documentos readAsDataURL codifica a base64

Arun Killu
fuente
1
¿La cadena de salida no parece ser base64?
quarks
1
@xybrek Si imprime read.result, verá base64 en la cadena misma.
Nawaf Alsulami
27
console.log (base64data.substr (base64data.indexOf (',') + 1));
palota
9
onloadenddebería aparecer antes readAsDataURLen caso de que ocurra algo extraño y termine de cargarse antes de llegar a la siguiente línea de código. Obviamente esto nunca sucedería, pero sigue siendo una buena práctica.
3ocene
2
Esta respuesta es incorrecta, agrega caracteres no base64 al frente de la cadena.
Joshua Smith el
28

esto funcionó para mí:

var blobToBase64 = function(blob, callback) {
    var reader = new FileReader();
    reader.onload = function() {
        var dataUrl = reader.result;
        var base64 = dataUrl.split(',')[1];
        callback(base64);
    };
    reader.readAsDataURL(blob);
};
yeahdixon
fuente
¿Cuál es el argumento cb?
Compañero extraño
1
@FellowStranger comúnmente devolución de llamada, utilizada como blobToBase64 (myBlob, function (base64String) {/ * use base64String * /}), porque es asíncrono
Leonard Pauli
@yeahdixon, parece que necesito tu ayuda. Mira esto: stackoverflow.com/questions/46192069/…
Success Man
7
var audioURL = window.URL.createObjectURL(blob);
audio.src = audioURL;

var reader = new window.FileReader();
reader.readAsDataURL(blob);
reader.onloadend = function () {
     base64data = reader.result;
     console.log(base64data);
}
zinsat
fuente
Bien, @Vemonus porque FileReader expone en atributo de resultado como base64, funciona perfectamente.
Cami Rodriguez
6

Hay una forma pura de JavaSript que no depende de ninguna pila:

const blobToBase64 = blob => {
  const reader = new FileReader();
  reader.readAsDataURL(blob);
  return new Promise(resolve => {
    reader.onloadend = () => {
      resolve(reader.result);
    };
  });
};

Para usar esta función auxiliar, debe establecer una devolución de llamada, por ejemplo:

blobToBase64(blobData).then(res => {
  // do what you wanna do
  console.log(res); // res is base64 now
});

Escribo esta función auxiliar para mi problema en el proyecto React Native, quería descargar una imagen y luego almacenarla como una imagen en caché:

fetch(imageAddressAsStringValue)
  .then(res => res.blob())
  .then(blobToBase64)
  .then(finalResult => { 
    storeOnMyLocalDatabase(finalResult);
  });
AmerllicA
fuente
5
function bufferToBinaryString(arrayBuffer){
    return String.fromCharCode(...new Uint8Array(arrayBuffer));
}
(async () => console.log(btoa(bufferToBinaryString(await new Response(blob).arrayBuffer()))))();

o

function bufferToBinaryString(arrayBuffer){
    return String.fromCharCode(...new Uint8Array(arrayBuffer));
}
new Response(blob).arrayBuffer().then(arr_buf => console.log(btoa(bufferToBinaryString(arr_buf)))))

vea el constructor de Response , puede convertirlo [blob, buffer source form data, readable stream, etc.]en Response , que luego se puede convertir [json, text, array buffer, blob]con método asíncrono / devoluciones de llamada.

editar: como mencionó @Ralph, convertir todo en una cadena utf-8 causa problemas (desafortunadamente, la API de respuesta no proporciona una forma de convertir a una cadena binaria), por lo que el búfer de matriz se usa como intermedio, lo que requiere dos pasos más (convertirlo a matriz de bytes ENTONCES a cadena binaria), si insiste en usar el btoamétodo nativo .

Valen
fuente
.text () decodifica usando UTF8, ¿qué sucede si la respuesta tiene código binario? Creo que esto fallará para los datos que no son de texto
Ralph
Veo su punto, modificó la respuesta (aunque se vuelve bastante larga). En este punto, sería mejor no insistir enbtoa
Valen
4

Puedes solucionar el problema:

var canvas = $('#canvas'); 
var b64Text = canvas.toDataURL();
b64Text = b64Text.replace('data:image/png;base64,','');
var base64Data = b64Text;

Espero que esto te ayude

Ali Sadri
fuente
4

Entonces, el problema es que desea cargar una imagen base 64 y tiene una URL de blob. Ahora la respuesta que funcionará en todos los navegadores html 5 es: Hacer:

  var fileInput = document.getElementById('myFileInputTag');
  var preview = document.getElementById('myImgTag');

  fileInput.addEventListener('change', function (e) {
      var url = URL.createObjectURL(e.target.files[0]);
      preview.setAttribute('src', url);
  });
function Upload()
{
     // preview can be image object or image element
     var myCanvas = document.getElementById('MyCanvas');
     var ctx = myCanvas.getContext('2d');
     ctx.drawImage(preview, 0,0);
     var base64Str = myCanvas.toDataURL();
     $.ajax({
         url: '/PathToServer',
         method: 'POST',
         data: {
             imageString: base64Str
         },
     success: function(data) { if(data && data.Success) {}},
     error: function(a,b,c){alert(c);}
     });
 }
AW
fuente
0

Quería algo donde tuviera acceso al valor de base64 para almacenar en una lista y para mí, agregar oyente de eventos funcionó. Solo necesita FileReader, que leerá el blob de imágenes y devolverá el base64 en el resultado.

createImageFromBlob(image: Blob) {
    const reader = new FileReader();
    const supportedImages = []; // you can also refer to some global variable
    reader.addEventListener(
      'load',
      () => {
        // reader.result will have the required base64 image
        const base64data = reader.result;
        supportedImages.push(base64data); // this can be a reference to global variable and store the value into that global list so as to use it in the other part
      },
      false
    );
    // The readAsDataURL method is used to read the contents of the specified Blob or File.
    if (image) {
      reader.readAsDataURL(image);
    }
 }

La parte final es readAsDataURL, que es muy importante para leer el contenido del Blob especificado.

Asif Karim Bherani
fuente
-2

La forma más fácil en una sola línea de código

var base64Image = new Buffer (blob, 'binario') .toString ('base64');

Vishnu IT
fuente
18
Debido a que esta respuesta usa API de nodo y no responde la pregunta original sobre Blob (API de navegador).
RReverser
¿Qué es el buffer?
IntoTheDeep
1
Obtengo TypeError no capturado: el primer argumento debe ser una cadena, Buffer, ArrayBuffer, Array u objeto tipo matriz.
Incorrecto
@TeodorKolev es específico de Node.js
Jader Dias