แปลง blob เป็น base64


154

นี่คือตัวอย่างโค้ดที่ฉันต้องการทำ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);

ปัญหาเกิดจากโค้ดด้านล่างตัวแปรต้นทางที่สร้างขึ้นเป็นโมฆะ

อัปเดต:

มีวิธีที่ง่ายกว่าในการดำเนินการกับ JQuery เพื่อให้สามารถสร้าง Base64 String จากไฟล์ Blob ตามโค้ดด้านบนได้หรือไม่?

คำตอบ:


308
 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 ในสตริงนั้นเอง
Nawaf Alsulami

27
console.log (base64data.substr (base64data.indexOf (',') + 1));
palota

11
onloadendควรมาก่อนreadAsDataURLเผื่อมีอะไรแปลก ๆ เกิดขึ้นและโหลดเสร็จก่อนที่จะถึงบรรทัดถัดไปของโค้ด เห็นได้ชัดว่าสิ่งนี้จะไม่เกิดขึ้น แต่ก็ยังคงเป็นแนวทางปฏิบัติที่ดี
3ocene

3
คำตอบนี้ไม่ถูกต้องจะต่อท้ายอักขระ none-base64 ที่ด้านหน้าของสตริง
Joshua Smith

32

สิ่งนี้ได้ผลสำหรับฉัน:

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

ทะเลาะcbอะไรกัน
Fellow Stranger

1
@FellowStranger เรียกกลับโดยทั่วไปใช้เช่น blobToBase64 (myBlob ฟังก์ชัน (base64String) {/ * ใช้ base64String * /}) เนื่องจากเป็นแบบ async
Leonard Pauli

@yeahdixon ดูเหมือนว่าฉันต้องการความช่วยเหลือจากคุณ ดูที่นี้: stackoverflow.com/questions/46192069/…
Success Man

คุณจะรอการประหารชีวิตได้อย่างไร? ฉันมักจะไม่ได้กำหนด
MauriR

การโทรกลับหมายถึงฟังก์ชันที่ส่งผ่านซึ่งจะเริ่มทำงานเมื่อเสร็จสมบูรณ์
yeahdixon

13

มีวิธี 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);
  });

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

ดี @Vemonus เนื่องจาก FileReader แสดงในแอตทริบิวต์ผลลัพธ์เป็น base64 ทำงานได้อย่างสมบูรณ์
Cami Rodriguez

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

โปรดดูตัวสร้างของการตอบกลับคุณสามารถเปลี่ยน[blob, buffer source form data, readable stream, etc.]เป็นการตอบสนองซึ่งสามารถเปลี่ยนเป็น[json, text, array buffer, blob]วิธีการ async / การเรียกกลับได้

แก้ไข: ตามที่ @Ralph กล่าวถึงการเปลี่ยนทุกอย่างเป็นสตริง utf-8 ทำให้เกิดปัญหา (น่าเสียดายที่ Response API ไม่มีวิธีการแปลงเป็นสตริงไบนารี) ดังนั้นจึงใช้อาร์เรย์บัฟเฟอร์เป็นตัวกลางแทนซึ่งต้องใช้อีกสองขั้นตอน (การแปลงเป็น ไบต์อาร์เรย์แล้วไปยังสตริงไบนารี) หากคุณยืนยันที่จะใช้btoaวิธีดั้งเดิม


.text () ถอดรหัสโดยใช้ UTF8 จะเกิดอะไรขึ้นหากการตอบสนองมีรหัสไบนารี ฉันเชื่อว่าสิ่งนี้จะล้มเหลวสำหรับข้อมูลที่ไม่ใช่ข้อความ
Ralph

ฉันเห็นประเด็นของคุณแล้วแก้ไขคำตอบ (มันค่อนข้างยาว) เมื่อมาถึงจุดนี้มันจะดีกว่าถ้าไม่ยืนกรานbtoa
Valen

5

ดังนั้นปัญหาคือคุณต้องการอัปโหลดภาพพื้นฐาน 64 และคุณมี URL หยด ตอนนี้คำตอบที่ใช้ได้กับเบราว์เซอร์ 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);}
     });
 }

ทางออกที่ยอดเยี่ยม
Shakthifuture

4

คุณสามารถแก้ไขปัญหาได้โดย:

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

ฉันหวังว่านี่จะช่วยคุณได้


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 = บัฟเฟอร์ใหม่ (หยด, 'ไบนารี') .toString ('base64');


18
เนื่องจากคำตอบนี้ใช้ Node API ดังนั้นจึงไม่ตอบคำถามเดิมเกี่ยวกับ Blob (browser API)
RReverser

บัฟเฟอร์คืออะไร?
IntoTheDeep

1
ฉันได้รับ Uncaught TypeError: อาร์กิวเมนต์แรกต้องเป็นสตริง, บัฟเฟอร์, ArrayBuffer, Array หรือวัตถุคล้ายอาร์เรย์
ผิด

@TeodorKolev เฉพาะสำหรับ Node.js
Jader Dias
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.