Converter blob em base64

140

Este é um trecho do código que eu quero fazer Blobpara a Base64string:

Esta parte comentada funciona e, quando o URL gerado por isso é definido como img src, ele exibe a imagem:

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

O problema está no código inferior, a variável de origem gerada é nula

Atualizar:

Existe uma maneira mais fácil de fazer isso com o JQuery para poder criar String Base64 a partir do arquivo Blob, como no código acima?

quarks
fonte

Respostas:

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

Forme os documentos readAsDataURL codificados para base64

Arun Killu
fonte
1
A String de saída não parece com base64?
quarks
1
@xybrek Se você imprimir read.result, verá base64 na própria string.
Nawaf Alsulami
27
console.log (base64data.substr (base64data.indexOf (',') + 1));
palota
9
onloadenddeve vir antes readAsDataURL, caso algo estranho aconteça e o carregamento seja concluído antes de chegar à próxima linha de código. Obviamente, isso nunca aconteceria, mas ainda é uma boa prática.
3ocene
2
Esta resposta está incorreta, acrescenta caracteres não-base64 à frente da string.
Joshua Smith
28

isso funcionou para mim:

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
fonte
Qual é o argumento cb?
Companheiro Estrangeiro
1
@FellowStranger comumente chamada de retorno, usado como blobToBase64 (myBlob, function (base64String) {/ * usar o base64String * /}), porque é assíncrona
Leonard Pauli
@yeahdixon, parece que preciso da sua ajuda. Veja isto: 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
fonte
Bom, @Vemonus porque o FileReader expõe no atributo resultado como base64, funciona perfeitamente.
Cami Rodriguez
6

Existe uma maneira JavaSript pura que não depende de nenhuma pilha:

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

Para usar esta função auxiliar, você deve definir um retorno de chamada, exemplo:

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

Eu escrevi essa função auxiliar para o meu problema no projeto React Native, queria fazer o download de uma imagem e armazená-la como uma imagem em cache:

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

ou

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

consulte o construtor do Response , você pode se transformar [blob, buffer source form data, readable stream, etc.]em Response , que pode ser transformado em [json, text, array buffer, blob]método assíncrono / retornos de chamada.

edit: como o @Ralph mencionou, transformar tudo em string utf-8 causa problemas (infelizmente a API de resposta não fornece uma maneira de converter em string binária); portanto, o buffer do array é usado como intermediário, o que requer mais duas etapas (convertendo-o em matriz de bytes THEN a string binária), se você insistir em usar o btoamétodo nativo .

Valen
fonte
.text () decodifica usando UTF8, o que acontece se a resposta tiver código binário? Eu acredito que isso irá falhar para dados não-texto
Ralph
Entendo, alterei a resposta (ela se torna bastante longa). Neste ponto, seria melhor não insistirbtoa
Valen
4

você pode corrigir o problema:

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

Espero que isso lhe ajude

Ali Sadri
fonte
4

Portanto, o problema é que você deseja fazer upload de uma imagem de base 64 e ter um URL de blob. Agora, a resposta que funcionará em todos os navegadores html 5 é: Faça:

  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
fonte
0

Eu queria algo em que tivesse acesso ao valor base64 para armazenar em uma lista e, para mim, adicionar o ouvinte de evento funcionou. Você só precisa do FileReader, que lerá o blob da imagem e retornará a base64 no 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);
    }
 }

A parte final é o readAsDataURL, que é muito importante e está sendo usado para ler o conteúdo do Blob especificado

Asif Karim Bherani
fonte
-2

A maneira mais fácil em uma única linha de código

var base64Image = novo Buffer (blob, 'binário') .toString ('base64');

Vishnu IT
fonte
18
Como esta resposta usa APIs de nó, não responde à pergunta original sobre o Blob (API do navegador).
RReverser
O que é Buffer?
IntoTheDeep
1
Eu recebo o TypeError não capturado: o primeiro argumento deve ser uma seqüência de caracteres, Buffer, ArrayBuffer, Array ou objeto semelhante a um array.
Errado
@TeodorKolev é específico para Node.js
Jader Dias