Konwertuj obiekt BLOB na base64

154

To jest fragment kodu, który chcę zrobić, Blobaby Base64napisać:

Ta skomentowana część działa i gdy wygenerowany przez to adres URL jest ustawiony na img src, wyświetla obraz:

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

Problem polega na tym, że z niższym kodem wygenerowana zmienna źródłowa ma wartość null

Aktualizacja:

Czy istnieje łatwiejszy sposób na zrobienie tego za pomocą JQuery, aby móc utworzyć ciąg Base64 z pliku Blob, jak w powyższym kodzie?

kwarki
źródło

Odpowiedzi:

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

Utwórz dokumentację readAsDataURL kodującą do base64

Arun Killu
źródło
1
Ciąg wyjściowy nie wygląda jak base64?
kwarki
1
@xybrek Jeśli wypiszesz read.result, zobaczysz base64 w samym ciągu.
Nawaf Alsulami
27
console.log (base64data.substr (base64data.indexOf (',') + 1));
palota
11
onloadendpowinien pojawić się wcześniej, readAsDataURLna wypadek gdyby wydarzyło się coś dziwnego i ładowanie kończy się, zanim osiągnie następny wiersz kodu. Oczywiście to nigdy by się nie wydarzyło, ale nadal jest to dobra praktyka.
3ocen
3
Ta odpowiedź jest niepoprawna, dodaje znaki inne niż base64 na początku ciągu.
Joshua Smith
32

to zadziałało dla mnie:

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
źródło
Jaki jest argument cb?
Fellow Stranger
1
@FellowStranger często wywołuje zwrotne, używane jak blobToBase64 (myBlob, function (base64String) {/ * używają base64String * /}), ponieważ jest asynchroniczne
Leonard Pauli
@yeahdixon, Wygląda na to, że potrzebuję twojej pomocy. Spójrz na to: stackoverflow.com/questions/46192069/…
Success Man
Jak czekasz na wykonanie? Zawsze jestem niezdefiniowany
MauriR
wywołanie zwrotne ma być funkcją, która jest przekazywana i uruchamia się po zakończeniu
tak,
13

Istnieje czysty sposób JavaSript, który nie jest zależny od żadnych stosów:

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

Aby skorzystać z tej funkcji pomocniczej, należy ustawić wywołanie zwrotne, na przykład:

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

Piszę tę funkcję pomocniczą dla mojego problemu w projekcie React Native, chciałem pobrać obraz, a następnie zapisać go jako obraz w pamięci podręcznej:

fetch(imageAddressAsStringValue)
  .then(res => res.blob())
  .then(blobToBase64)
  .then(finalResult => { 
    storeOnMyLocalDatabase(finalResult);
  });
AmerllicA
źródło
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
źródło
Fajnie, @Vemonus, ponieważ FileReader eksponuje atrybut wyniku jako base64, działa idealnie.
Cami Rodriguez
6
function bufferToBinaryString(arrayBuffer){
    return String.fromCharCode(...new Uint8Array(arrayBuffer));
}
(async () => console.log(btoa(bufferToBinaryString(await new Response(blob).arrayBuffer()))))();

lub

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

zobacz konstruktor Response , możesz zamienić go [blob, buffer source form data, readable stream, etc.]na Response , który następnie może zostać zamieniony na [json, text, array buffer, blob]metodę asynchroniczną / wywołania zwrotne.

edit: jak wspomniał @Ralph, zamiana wszystkiego na łańcuch utf-8 powoduje problemy (niestety API Response nie zapewnia sposobu konwersji na ciąg binarny), więc bufor tablicy jest używany jako pośredni, co wymaga dwóch dodatkowych kroków (konwersja do tablica bajtów TO do łańcucha binarnego), jeśli nalegasz na użycie btoametody natywnej .

Valen
źródło
.text () dekoduje za pomocą UTF8, co się stanie, jeśli odpowiedź zawiera kod binarny? Wierzę, że to się nie powiedzie w przypadku danych innych niż tekstowe
Ralph
Rozumiem twój punkt widzenia, poprawiłem odpowiedź (jest jednak dość długa). W tym momencie lepiej nie nalegaćbtoa
Valen
5

Więc problem polega na tym, że chcesz przesłać podstawowy obraz 64 i masz adres URL obiektu BLOB. Teraz odpowiedź, która będzie działać we wszystkich przeglądarkach HTML 5, brzmi: Zrób:

  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
źródło
Doskonałe rozwiązanie
Shakthifuture
4

możesz rozwiązać problem poprzez:

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

Mam nadzieję, że to ci pomoże

Ali Sadri
źródło
1

Chciałem coś, w czym mam dostęp do wartości base64, aby zapisać na liście, a dla mnie dodanie detektora zdarzeń zadziałało. Potrzebujesz tylko FileReader, który odczyta blob obrazu i zwróci wynik base64.

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

Ostatnią częścią jest readAsDataURL, który jest bardzo ważny, aby odczytać zawartość określonego obiektu Blob

Asif Karim Bherani
źródło
-2

Najłatwiej w jednej linii kodu

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

Vishnu IT
źródło
18
Ponieważ ta odpowiedź wykorzystuje interfejsy API węzła, a więc nie odpowiada na pierwotne pytanie dotyczące obiektu Blob (API przeglądarki).
RReverser
Co to jest bufor?
IntoTheDeep
1
Otrzymuję Uncaught TypeError: Pierwszy argument musi być ciągiem, buforem, ArrayBuffer, Array lub obiektem podobnym do tablicy.
Niewłaściwy
@TeodorKolev jest specyficzny dla Node.js
Jader Dias