Конвертировать BLOB-объекты в base64

140

Это фрагмент кода, который я хочу сделать Blobдля Base64строки:

Эта закомментированная часть работает, и когда URL-адрес, сгенерированный ею, установлен на img src, он отображает изображение:

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

Проблема заключается в нижнем коде, сгенерированная исходная переменная имеет значение NULL.

Обновить:

Есть ли более простой способ сделать это с помощью JQuery, чтобы иметь возможность создавать строку Base64 из файла Blob, как в приведенном выше коде?

кварки
источник

Ответы:

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

Форма документов readAsDataURL кодируется в base64

Арун Киллу
источник
1
Выходная строка не похожа на base64?
кварки
1
@xybrek Если вы напечатаете read.result, вы увидите base64 в самой строке.
Наваф Алсулами
27
console.log (base64data.substr (base64data.indexOf (',') + 1));
Palota
9
onloadendдолжен появиться раньше readAsDataURLна тот случай, если произойдет что-то странное, и он завершит загрузку до того, как достигнет следующей строки кода. Очевидно, этого никогда не произойдет, но это все еще хорошая практика.
3
2
Этот ответ неверен, он добавляет символы, отличные от base64, в начало строки.
Джошуа Смит
28

это сработало для меня:

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
источник
Какой аргумент cb?
Fellow Stranger
1
@FellowStranger обычно выполняет обратный вызов, используется как blobToBase64 (myBlob, function (base64String) {/ * использовать base64String * /}), потому что он асинхронный
Леонард Паули
@yeahdixon, кажется мне нужна твоя помощь. Посмотрите на это: 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
источник
Хорошо, @Vemonus, потому что FileReader выставляет атрибут результата как base64, отлично работает.
Ками Родригес,
7

Существует чистый способ JavaSript, не зависящий от каких-либо стеков:

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

Для использования этой вспомогательной функции вы должны установить обратный вызов, например:

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

Я пишу эту вспомогательную функцию для моей проблемы в проекте React Native, я хотел загрузить изображение, а затем сохранить его как кэшированное изображение:

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

или

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

см . конструктор Response , вы можете превратить его [blob, buffer source form data, readable stream, etc.]в Response , который затем можно преобразовать [json, text, array buffer, blob]с помощью асинхронного метода / обратных вызовов.

edit: как уже упоминалось @Ralph, превращение всего в строку utf-8 вызывает проблемы (к сожалению, в Response API нет способа преобразования в двоичную строку), поэтому буфер массива используется вместо этого в качестве промежуточного, что требует еще двух шагов (преобразование его в байтовый массив THEN в двоичную строку), если вы настаиваете на использовании собственного btoaметода.

Вален
источник
.text () декодируется с использованием UTF8, что произойдет, если ответ будет иметь двоичный код? Я считаю, что это не сработает для нетекстовых данных
Ральф
Я понимаю вашу точку зрения, поправил ответ (правда, он становится довольно длинным). На данном этапе лучше бы не настаиватьbtoa
Вален
4

вы можете решить проблему:

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

Я надеюсь, что это поможет вам

Али Садри
источник
4

Итак, проблема в том, что вы хотите загрузить изображение base 64 и у вас есть URL-адрес blob. Теперь ответ, который будет работать во всех браузерах html 5: Сделайте:

  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
источник
1

Я хотел что-то, где у меня есть доступ к значению base64 для хранения в списке, и для меня сработало добавление прослушивателя событий. Вам просто понадобится FileReader, который прочитает большой двоичный объект изображения и вернет в результате 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);
    }
 }

Последняя часть - это readAsDataURL, который очень важен для чтения содержимого указанного Blob.

Асиф Карим Бхерани
источник
-2

Самый простой способ в одной строчке кода

var base64Image = новый буфер (blob, 'двоичный') .toString ('base64');

Вишну ИТ
источник
18
Поскольку в этом ответе используются API-интерфейсы Node, поэтому он не отвечает на исходный вопрос о Blob (API-интерфейсе браузера).
RReverser
Что такое буфер?
IntoTheDeep
1
Я получаю Uncaught TypeError: Первый аргумент должен быть строкой, Buffer, ArrayBuffer, Array или массивоподобным объектом.
Неправильно
@TeodorKolev это специфично для Node.js
Jader Dias