繁体   English   中英

如何使用 JavaScript 将图像转换为 Base64 字符串?

[英]How can I convert an image into Base64 string using JavaScript?

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

是否有任何 JavaScript 文件? 否则,我该如何转换它?

您可以选择多种方法:

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.方法:Canvas

将图像加载到 Image-Object 中,将其绘制到未污染的 canvas 并将 canvas 转换回 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) } )

详细地

支持的输入格式:

image/png , image/jpeg , image/jpg , image/gif , image/bmp , image/tiff , image/x-icon , image/svg+xml , image/webp , image/xxx

支持的 output 格式:

image/pngimage/jpegimage/webp (铬)

浏览器支持:


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)" />

您可以使用 HTML5 <canvas>

创建一个 canvas,将图像加载到其中,然后使用toDataURL()获取 Base64 表示(实际上,它是一个data: ZE6B391A8D2C4D45902A23A8B65864-en 编码的图像)。

该片段可以将您的字符串、图像甚至视频文件转换为 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>

基本上,如果您的图像是

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

这是我所做的:

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

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

演示: 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>

如果你有一个文件 object,这个简单的 function 可以工作:

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

这是您可以使用 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))
    }

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

将图像转换为已加载的 canvas

uploadProfile(e) {

    let file = e.target.files[0];
    let reader = new FileReader();

    reader.onloadend = function() {
        console.log('RESULT', reader.result)
    }
    reader.readAsDataURL(file);
}

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

试试这个代码:

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

$("#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 数据存储在隐藏文件中以供使用。

我最终使用了返回functionfunction

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


您可以在任何异步 function中使用此方法。 然后您可以await转换后的图像并继续说明。

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

需要利用 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)

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

尝试这个:

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

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

要解码 Base64 编码的字符串:

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

如果您遇到 cors 原始错误,则有一个名为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);
    }));
  }

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

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

假设您在浏览器中执行此操作:

等待:

import axios from 'axios'

const response = await axios.get(url, { responseType: 'blob' });
return window.URL.createObjectURL(response.data);

配promise

import axios from 'axios'

const response = await axios.get(url, { responseType: 'blob' })
  .then((response) => {
    const dataUrl = window.URL.createObjectURL(response.data);
    // do something with your url
  });

这很简单。 1> 只需拨打 function 并传递您的图像。 2> 保存返回值,在需要的地方使用。

//call like this
const convertedFile = await imageToBase64(fileObj);
console.log("convertedFile",convertedFile);

//this is the required function

 async function  imageToBase64(image) {
 const reader = new FileReader();
 reader.readAsDataURL(image);
 const data= await new Promise((resolve, reject) => {

   reader.onload = () => resolve(reader.result);

   reader.onerror = error => reject(error);

  });
return data;
}

export default imageToBase64;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM