【问题标题】:How can I convert an image into Base64 string using JavaScript?如何使用 JavaScript 将图像转换为 Base64 字符串?
【发布时间】:2011-09-03 06:21:22
【问题描述】:

我需要将我的图像转换为 Base64 字符串,以便我可以将我的图像发送到服务器。

有这方面的 JavaScript 文件吗?不然怎么转换?

【问题讨论】:

标签: javascript base64


【解决方案1】:

您也可以通过 ding 来简单地提取 URL 的 base-64 部分:

var Base64URL = canvas.toDataURL('image/webp')
var Base64 = Base64URL.split(",")[1] //Returns the base64 part

【讨论】:

    【解决方案2】:

    如果您遇到 cors origin 错误,有一个名为 cors-fix 的简单代理将图像加载到服务器上并将其作为缓冲区数组返回。

    因此,我们可以使用 fetch 获取图像数据并使用 filereader 将其转换为 dataUrl,如 @HaNdTriX 所述。

      function toDataUrl(url) {
        fetch(`https://cors-fix.web.app/v1?url=${url}`)
        .then(data => data.blob().then(blob => {
          const reader = new FileReader();
    
          reader.onloadend = () =>  {
            console.log(reader.result);
          };
    
          reader.onerror = () => {
            console.log('reader error');
          };
    
          reader.readAsDataURL(blob);
        }));
      }
    

    【讨论】:

      【解决方案3】:

      我最终使用了一个function,它返回一个Promise

      const getImg64 = async() => {
        const convertImgToBase64URL = (url) => {
        console.log(url)
          return new Promise((resolve, reject) => {
            const img = new Image();
            img.crossOrigin = 'Anonymous';
            img.onload = () => {
                let canvas = document.createElement('CANVAS')
                const ctx = canvas.getContext('2d')
                canvas.height = img.height;
                canvas.width = img.width;
                ctx.drawImage(img, 0, 0);
                const dataURL = canvas.toDataURL();
                canvas = null;
                resolve(dataURL)
            }
            img.src = url;
          })
        }
        //for the demonstration purposes I used proxy server to avoid cross origin error
        const proxyUrl = 'https://cors-anywhere.herokuapp.com/'
        const image = await convertImgToBase64URL(proxyUrl+'https://image.shutterstock.com/image-vector/vector-line-icon-hello-wave-260nw-1521867944.jpg')
        console.log(image)
      }
      getImg64()

      您可以在任何async function 中使用此方法。然后你就可以 await 获取转换后的图像并继续说明。

      【讨论】:

      • 我有一个类似的解决方案,它可以工作,谢谢!
      【解决方案4】:

      您可以选择多种方法:

      1。方法:文件阅读器

      通过XMLHttpRequest 将图像加载为blob,并使用FileReader API (readAsDataURL()) 将其转换为dataURL

      function toDataURL(url, callback) {
        var xhr = new XMLHttpRequest();
        xhr.onload = function() {
          var reader = new FileReader();
          reader.onloadend = function() {
            callback(reader.result);
          }
          reader.readAsDataURL(xhr.response);
        };
        xhr.open('GET', url);
        xhr.responseType = 'blob';
        xhr.send();
      }
      
      toDataURL('https://www.gravatar.com/avatar/d50c83cc0c6523b4d3f6085295c953e0', function(dataUrl) {
        console.log('RESULT:', dataUrl)
      })

      此代码示例也可以使用 WHATWG fetch API 实现:

      const toDataURL = url => fetch(url)
        .then(response => response.blob())
        .then(blob => new Promise((resolve, reject) => {
          const reader = new FileReader()
          reader.onloadend = () => resolve(reader.result)
          reader.onerror = reject
          reader.readAsDataURL(blob)
        }))
      
      
      toDataURL('https://www.gravatar.com/avatar/d50c83cc0c6523b4d3f6085295c953e0')
        .then(dataUrl => {
          console.log('RESULT:', dataUrl)
        })

      这些方法:

      • 缺乏浏览器支持
      • 有更好的压缩率
      • 也适用于其他文件类型

      浏览器支持:


      2。方法:帆布

      将图像加载到 Image-Object 中,将其绘制到未污染的画布上,然后将画布转换回 dataURL。

      function toDataURL(src, callback, outputFormat) {
        var img = new Image();
        img.crossOrigin = 'Anonymous';
        img.onload = function() {
          var canvas = document.createElement('CANVAS');
          var ctx = canvas.getContext('2d');
          var dataURL;
          canvas.height = this.naturalHeight;
          canvas.width = this.naturalWidth;
          ctx.drawImage(this, 0, 0);
          dataURL = canvas.toDataURL(outputFormat);
          callback(dataURL);
        };
        img.src = src;
        if (img.complete || img.complete === undefined) {
          img.src = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==";
          img.src = src;
        }
      }
      
      toDataURL(
        'https://www.gravatar.com/avatar/d50c83cc0c6523b4d3f6085295c953e0',
        function(dataUrl) {
          console.log('RESULT:', dataUrl)
        }
      )

      In detail

      支持的输入格式:

      image/pngimage/jpegimage/jpgimage/gifimage/bmpimage/tiffimage/x-iconimage/svg+xmlimage/webpimage/xxx

      支持的输出格式:

      image/png, image/jpeg, image/webp(chrome)

      浏览器支持:


      3。方法:来自本地文件系统的图像

      如果您想从用户文件系统转换图像,您需要采用不同的方法。 使用FileReader API:

      function encodeImageFileAsURL(element) {
        var file = element.files[0];
        var reader = new FileReader();
        reader.onloadend = function() {
          console.log('RESULT', reader.result)
        }
        reader.readAsDataURL(file);
      }
      <input type="file" onchange="encodeImageFileAsURL(this)" />

      【讨论】:

      • 我无法在 Chrome 中工作:Image from origin **** has been blocked from loading by Cross-Origin Resource Sharing policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://fiddle.jshell.net' is therefore not allowed access.
      • 以防万一这绊倒了其他人,这个例程在它返回的字符串中包含“data:image/jpg;base64”标题,所以你不需要附加它。跨度>
      • Warnin2:内容有问题。在此过程中的某个地方,数据有可能被损坏/更改(尽管可能不会太多),至少在某些图像上的 Firefox 35 上发生这种情况,base64 与 php 创建的 base64 不同图片。
      • 是的,没错。一些数据可能会丢失,因为我们实际上将图像绘制到画布元素 (developer.mozilla.org/en-US/docs/Web/API/…),然后将其转换为 dataURL (developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/…)。
      • 方法:FileReader (2) 比方法 Canvas 工作得更快。在大照片上进行了测试。希望它对某些人有所帮助。
      【解决方案5】:

      需要利用 reader 将 blob 转换为 base64,更喜欢使用 async-await 语法,所以我选择将 reader 逻辑提取到 helper 中,如下所示:

      //* Convert resBlob to base64
      export const blobToData = (blob: Blob) => {
        return new Promise((resolve) => {
          const reader = new FileReader()
          reader.onloadend = () => resolve(reader.result)
          reader.readAsDataURL(blob)
        })
      }
      

      并在主代码中使用 await 调用它:

      //* Convert resBlob to dataUrl and resolve
      const resData = await blobToData(resBlob)
      

      【讨论】:

        【解决方案6】:

        我发现最安全可靠的方法是使用FileReader()

        演示:Image to Base64

        <!DOCTYPE html>
        <html>
          <head>
            <meta charset="UTF-8">
          </head>
          <body>
            <input id="myinput" type="file" onchange="encode();" />
            <div id="dummy">
            </div>
            <div>
              <textarea style="width:100%;height:500px;" id="txt">
              </textarea>
            </div>
            <script>
              function encode() {
                var selectedfile = document.getElementById("myinput").files;
                if (selectedfile.length > 0) {
                  var imageFile = selectedfile[0];
                  var fileReader = new FileReader();
                  fileReader.onload = function(fileLoadedEvent) {
                    var srcData = fileLoadedEvent.target.result;
                    var newImage = document.createElement('img');
                    newImage.src = srcData;
                    document.getElementById("dummy").innerHTML = newImage.outerHTML;
                    document.getElementById("txt").value = document.getElementById("dummy").innerHTML;
                  }
                  fileReader.readAsDataURL(imageFile);
                }
              }
            </script>
          </body>
        </html>
        

        更新 - 与 @AnniekJ 请求的注释相同的代码:

        <!DOCTYPE html>
        <html>
          <head>
            <meta charset="UTF-8">
          </head>
          <body>
            <input id="myinput" type="file" onchange="encode();" />
            <div id="dummy">
            </div>
            <div>
              <textarea style="width:100%;height:500px;" id="txt">
              </textarea>
            </div>
            <script>
              function encode() {
                // Get the file objects that was selected by the user from myinput - a file picker control
                var selectedfile = document.getElementById("myinput").files;
                // Check that the user actually selected file/s from the "file picker" control
                // Note - selectedfile is an array, hence we check it`s length, when length of the array
                // is bigger than 0 than it means the array containes file objects
                if (selectedfile.length > 0) {
                  // Set the first file object inside the array to this variable
                  // Note: if multiple files are selected we can itterate on all of the selectedfile array  using a for loop - BUT in order to not make this example complicated we only take the first file object that was selected
                  var imageFile = selectedfile[0];
                  // Set a filereader object to asynchronously read the contents of files (or raw data buffers) stored on the            user's computer, using File or Blob objects to specify the file or data to read. 
                  var fileReader = new FileReader();
                  // We declare an event of the fileReader class (onload event) and we register an anonimous function that will be executed when the event is raised. it is "trick" we preapare in order for the onload event to be raised after the last line of this code will be executed (fileReader.readAsDataURL(imageFile);) - please read about events in javascript if you are not familiar with "Events" 
                  fileReader.onload = function(fileLoadedEvent) {
                    // AT THIS STAGE THE EVENT WAS RAISED
                    // Here we are getting the file contents - basiccaly the base64 mapping
                    var srcData = fileLoadedEvent.target.result;
                    // We create an image html element dinamically in order to display the image
                    var newImage = document.createElement('img');
                    // We set the source of the image we created
                    newImage.src = srcData;
                    // ANOTHER TRICK TO EXTRACT THE BASE64 STRING
                    // We set the outer html of the new image to the div element
                    document.getElementById("dummy").innerHTML = newImage.outerHTML;
                    // Then we take the inner html of the div and we have the base64 string
                    document.getElementById("txt").value = document.getElementById("dummy").innerHTML;
                  }
                  // This line will raise the fileReader.onload event - note we are passing the file object here as an argument to the function of the event  
                  fileReader.readAsDataURL(imageFile);
                }
              }
            </script>
          </body>
        </html>
        

        【讨论】:

        • 嗨,我正在寻找一种将我的 Powerpoint AddIn 中的图像转换为 base64 的方法(因为否则我无法将它们添加到幻灯片中)并找到了您的回复。你能否再向我解释一下你在这里做什么?我对此很陌生,所以我并没有真正了解整个 FileReader。只是提供一些背景知识:我有一个字符串 selectedImages,它们是 .png,我想将它们转换为 base64 文件,然后能够将它们添加到 powerpoint 幻灯片中。
        • @AnniekJ 请在每行代码上方的评论中查看我的更新答案
        【解决方案7】:

        document.querySelector('input').onchange = e => {
          const fr = new FileReader()
          fr.onloadend = () => document.write(fr.result)
          fr.readAsDataURL(e.target.files[0])
        }
        &lt;input type="file"&gt;

        【讨论】:

          【解决方案8】:

          这是您可以使用 Javascript Promise 的方式。

          const getBase64 = (file) => new Promise(function (resolve, reject) {
              let reader = new FileReader();
              reader.readAsDataURL(file);
              reader.onload = () => resolve(reader.result)
              reader.onerror = (error) => reject('Error: ', error);
          })
          
          

          现在,在事件处理程序中使用它。

          const _changeImg = (e) => {
                  const file = e.target.files[0];
                  let encoded;
                  getBase64(file)
                    .then((result) => {
                      encoded = result;
                     })
                    .catch(e => console.log(e))
              }
          

          【讨论】:

          • 如果您只想更改图像以供预览,请改用URL.createObjectURL(file)
          【解决方案9】:
          uploadProfile(e) {
          
              let file = e.target.files[0];
              let reader = new FileReader();
          
              reader.onloadend = function() {
                  console.log('RESULT', reader.result)
              }
              reader.readAsDataURL(file);
          }
          

          【讨论】:

            【解决方案10】:

            这是我所做的:

            // Author James Harrington 2014
            function base64(file, callback){
              var coolFile = {};
              function readerOnload(e){
                var base64 = btoa(e.target.result);
                coolFile.base64 = base64;
                callback(coolFile)
              };
            
              var reader = new FileReader();
              reader.onload = readerOnload;
            
              var file = file[0].files[0];
              coolFile.filetype = file.type;
              coolFile.size = file.size;
              coolFile.filename = file.name;
              reader.readAsBinaryString(file);
            }
            

            这就是你如何使用它

            base64( $('input[type="file"]'), function(data){
              console.log(data.base64)
            })
            

            【讨论】:

            【解决方案11】:

            如果你有一个文件对象,这个简单的函数就可以工作:

            function getBase64 (file, callback) {
            
                const reader = new FileReader();
            
                reader.addEventListener('load', () => callback(reader.result));
            
                reader.readAsDataURL(file);
            }
            

            使用示例:

            getBase64(fileObjectFromInput, function(base64Data){
                console.log("Base64 of file is", base64Data); // Here you can have your code which uses Base64 for its operation, // file to Base64 by oneshubh
            });
            

            【讨论】:

            【解决方案12】:

            试试这个代码:

            对于文件上传更改事件,调用此函数:

            $("#fileproof").on('change', function () {
                readImage($(this)).done(function (base64Data) { $('#<%=hfimgbs64.ClientID%>').val(base64Data); });
            });
            
            function readImage(inputElement) {
                var deferred = $.Deferred();
            
                var files = inputElement.get(0).files;
            
                if (files && files[0]) {
                    var fr = new FileReader();
                    fr.onload = function (e) {
                        deferred.resolve(e.target.result);
                    };
                    fr.readAsDataURL(files[0]);
                } else {
                    deferred.resolve(undefined);
                }
            
                return deferred.promise();
            }
            

            将 Base64 数据存储在隐藏文件中以供使用。

            【讨论】:

            • 嗨拉维!我看你是比较新的。除非原始发帖人特别要求使用 jQuery、lodash 等库解决方案,否则每个人都最好使用最低限度的答案,在这种情况下,使用纯 javascript。如果您仍然想为 jQuery 做出贡献,请在您的条目中明确说明 :)
            【解决方案13】:

            据我所知,可以通过 FileReader() 将图像转换为 Base64 字符串,也可以将其存储在 canvas 元素中,然后使用 toDataURL() 来获取图像。我有类似的问题,你可以参考这个。

            Convert an image to canvas that is already loaded

            【讨论】:

              【解决方案14】:

              好吧,如果您使用的是Dojo Toolkit,它为我们提供了一种直接编码或解码为 Base64 的方法。

              试试这个:

              使用 dojox.encoding.base64 对字节数组进行编码:

              var str = dojox.encoding.base64.encode(myByteArray);
              

              解码 Base64 编码的字符串:

              var bytes = dojox.encoding.base64.decode(str);
              

              【讨论】:

              • @DownVoter - 亲爱的,如果你标记的是负面的东西,最好也指出错误。以便有人可以改进。据我了解,dojo 也是一个 JavaScript 库,那么如果你被允许使用 dojo,你绝对可以使用这种方法。
              【解决方案15】:

              您可以为此使用 HTML5 &lt;canvas&gt;

              创建一个画布,将您的图像加载到其中,然后使用toDataURL() 获取 Base64 表示(实际上,它是一个data: URL,但它包含 Base64 编码的图像)。

              【讨论】:

              • toDataURL 是否像 xhr 一样控制诸如 done/fail/always 之类的回调?
              • 我们可以将 2 个或更多画布提取为单个 PNG 吗?
              • 这种方法在违反 CORS 的情况下会失败。除此之外,这个解决方案应该解决这个问题。
              • 我们都知道二进制转base64会占用更多的数据,但是如果不使用reader.readAsDataURL的话,用canvas这种方式获取base64会增加更多,因为你可能也会松使用 toDataURL 时的所有图像压缩。除非您希望将每个图像都转换为特定格式。当您使用画布时,您还会丢失所有元数据,例如:EXIF、旋转、相机、地理位置等
              【解决方案16】:

              这个sn-p可以将你的字符串、图片甚至视频文件转换成Base64字符串数据。

              <input id="inputFileToLoad" type="file" onchange="encodeImageFileAsURL();" />
              <div id="imgTest"></div>
              <script type='text/javascript'>
                function encodeImageFileAsURL() {
              
                  var filesSelected = document.getElementById("inputFileToLoad").files;
                  if (filesSelected.length > 0) {
                    var fileToLoad = filesSelected[0];
              
                    var fileReader = new FileReader();
              
                    fileReader.onload = function(fileLoadedEvent) {
                      var srcData = fileLoadedEvent.target.result; // <--- data: base64
              
                      var newImage = document.createElement('img');
                      newImage.src = srcData;
              
                      document.getElementById("imgTest").innerHTML = newImage.outerHTML;
                      alert("Converted Base64 version is " + document.getElementById("imgTest").innerHTML);
                      console.log("Converted Base64 version is " + document.getElementById("imgTest").innerHTML);
                    }
                    fileReader.readAsDataURL(fileToLoad);
                  }
                }
              </script>

              【讨论】:

              • 不仅很棒,还绕过了跨域起源问题!有了这个,您可以允许用户提供他们自己的图像或来自 URL 的图像(因为 Windows 将自己获取它),在画布上绘制它们,并在仍然能够使用 .toDataURL() 等的同时使用它们。非常感谢!
              • 您好,如何将其应用于从远程 url 加载的图像而不会遇到跨域问题?谢谢
              • 这有时在 Chrome 78.0.3904.97 中有效,但有时它会使标签页崩溃。
              【解决方案17】:

              基本上,如果你的图片是

              <img id='Img1' src='someurl'>
              

              然后你可以像这样转换它

              var c = document.createElement('canvas');
              var img = document.getElementById('Img1');
              c.height = img.naturalHeight;
              c.width = img.naturalWidth;
              var ctx = c.getContext('2d');
              
              ctx.drawImage(img, 0, 0, c.width, c.height);
              var base64String = c.toDataURL();
              

              【讨论】:

              • 不幸的是,这仅适用于本地图像,如果您尝试使用远程图像(从网络中选择一个)它会将其写入(firefox)控制台:'SecurityError:操作不安全'。
              • 它可能适用于其他图像,但取决于该站点的 CORS 设置,并且必须指定为 &lt;img id='Img1' src='someurl' crossorigin='anonymous'&gt;
              • 在 Firefox 上,您可以暂时禁用该安全性。转到“about:config”并将属性“privacy.file_unique_origin”更改为 false
              【解决方案18】:

              您可以使用FileAPI,但它几乎不受支持。

              【讨论】:

                猜你喜欢
                • 2012-03-14
                • 1970-01-01
                • 2011-06-17
                • 1970-01-01
                • 2011-02-16
                • 2018-09-07
                相关资源
                最近更新 更多