【问题标题】:Convert blob to base64将 blob 转换为 base64
【发布时间】:2013-09-10 02:31:05
【问题描述】:

这是我想做的代码的 sn-p BlobBase64 字符串:

此注释部分有效,并且当由此生成的 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 来从 Blob 文件中创建 Base64 字符串,如上面的代码所示?

【问题讨论】:

    标签: javascript jquery


    【解决方案1】:
    var reader = new FileReader();
    reader.readAsDataURL(blob); 
    reader.onloadend = function() {
      var base64data = reader.result;                
      console.log(base64data);
    }
    

    形成docs readAsDataURL 编码为base64

    作为awaitable 函数:

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

    注意:如果不首先删除 Base64 编码数据之前的 Data-URL 声明,则无法将 blob 的结果直接解码为 Base64。要仅检索 Base64 编码的字符串,请首先从结果中删除 data:/;base64。

    【讨论】:

    • 输出字符串看起来不像base64?
    • @xybrek 如果您打印 read.result,您将在字符串本身中看到 base64。
    • console.log(base64data.substr(base64data.indexOf(',')+1));
    • onloadend 应该在 readAsDataURL 之前,以防万一发生奇怪的事情并且它在到达下一行代码之前完成加载。显然这永远不会发生,但这仍然是一种很好的做法。
    • 这个答案不正确,它在字符串前面附加了非 base64 字符。
    【解决方案2】:

    这对我有用:

    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 的论据是什么?
    • @FellowStranger 常用回调,类似 blobToBase64(myBlob, function(base64String) {/*使用 base64String*/}),因为它是异步的
    • @yeahdixon,看来我需要你的帮助。看看这个:stackoverflow.com/questions/46192069/…
    • 如何等待执行?我总是不确定
    • 回调是一个被传递的函数,在完成时触发
    【解决方案3】:

    您可以通过以下方式解决问题:

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

    希望对你有帮助

    【讨论】:

      【解决方案4】:
      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,可以完美运行。
      【解决方案5】:

      所以问题是你想上传一个 base 64 图像并且你有一个 blob 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);}
           });
       }
      

      【讨论】:

        【解决方案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)))))
        

        参见Response's constructor,您可以将[blob, buffer source form data, readable stream, etc.] 转换为Response,然后可以通过异步方法/回调将其转换为[json, text, array buffer, blob]

        编辑:正如@Ralph 提到的,将所有内容都转换为 utf-8 字符串会导致问题(不幸的是 Response API 没有提供转换为二进制字符串的方法),因此 array buffer 被用作中间值,这需要另外两个步骤(将其转换为字节数组 THEN 为二进制字符串),如果您坚持使用本机 btoa 方法。

        【讨论】:

        • .text() 使用 UTF8 解码,如果响应包含二进制代码会怎样?我相信这对于非文本数据会失败
        • 我明白你的意思,修改了答案(虽然它变得很长)。此时最好不要坚持btoa
        【解决方案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);
          });
        

        【讨论】:

          【解决方案8】:

          我想要一些我可以访问 base64 值的东西来存储到一个列表中,并且对我来说添加事件侦听器是可行的。您只需要读取图像 blob 并在结果中返回 base64 的 FileReader。

          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 的内容

          【讨论】:

            【解决方案9】:

            另一种方法是在FileReader 周围使用一个简单的包装器,返回Observable(sn-p 在TypeScript 中):

              function toBase64(blob: Blob): Observable<string> {
                const reader = new FileReader();
                reader.readAsDataURL(blob);
                return fromEvent(reader, 'load')
                  .pipe(map(() => (reader.result as string).split(',')[1]));
              }
            

            用法:

            toBase64(blob).subscribe(base64 => console.log(base64));
            

            【讨论】:

              【解决方案10】:
              async function blobToBase64(blob) {
                return new Promise((resolve, _) => {
                  const reader = new FileReader();
                  reader.onloadend = () => resolve(reader.result);
                  reader.readAsDataURL(blob);
                });
              }
              
              let blob = null; // <= your blob object goes here
              
              blobToBase64(blob)
                .then(base64String => console.log(base64String));
              

              另见:

              【讨论】:

                【解决方案11】:

                异步 ​​TypeScript 变体:

                async function blobToBase64Async(blob: Blob): Promise<string> {
                  return new Promise((resolve, reject) => {
                    const fileReader = new FileReader();
                    fileReader.onerror = (e) => reject(fileReader.error);
                    fileReader.onloadend = (e) => {
                      const dataUrl = fileReader.result as string;
                      // remove "data:mime/type;base64," prefix from data url
                      const base64 = dataUrl.substring(dataUrl.indexOf(',') + 1);
                      resolve(base64);
                    };
                    fileReader.readAsDataURL(blob);
                  });
                }
                

                示例用法:

                async function fetchToBase64Async(url: string, init?: RequestInit): Promise<string> {
                  try {
                    const response = await fetch(url, init);
                    if (!response.ok) {
                      const responseText = await response.text();
                      throw new Error("server status: " + response.status + "\n" + "server response:" + "\n" + responseText);
                    }
                    const blob = await response.blob();
                    const base64 = await blobToBase64Async(blob);
                    return base64;
                  } catch (e) {
                    throw new Error("failed to fetch: " + url + "\n" + "caused by: " + e);
                  }
                }
                
                async function demoUsage() {
                  const base64 = await fetchToBase64Async("https://httpstat.us/200", {
                    method: "POST",
                    headers: {
                      "Accept": "*/*",
                      "Authorization": "Bearer ...",
                    }
                  });
                  console.log(base64);
                }
                

                注意事项:

                • 我不明白为什么有些答案使用load 而不是loadend 事件
                • 我不明白为什么有些答案在设置事件处理程序之前会调用readAsDataURL

                【讨论】:

                  【解决方案12】:

                  打字稿版本:

                  const blob2Base64 = (blob:Blob):Promise<string> => {
                        return new Promise<string> ((resolve,reject)=> {
                             const reader = new FileReader();
                             reader.readAsDataURL(blob);
                             reader.onload = () => resolve(reader.result.toString());
                             reader.onerror = error => reject(error);
                         })
                        }
                  

                  用法:

                  blob2Base64(blob).then(res=>console.log(res))
                  

                  【讨论】:

                    猜你喜欢
                    • 2021-07-27
                    • 2021-06-20
                    • 1970-01-01
                    • 2015-03-14
                    • 2019-11-18
                    • 2018-10-07
                    • 2021-05-03
                    • 2017-01-05
                    • 2020-11-10
                    相关资源
                    最近更新 更多