Làm cách nào để chuyển đổi hình ảnh thành chuỗi Base64 bằng JavaScript?


500

Tôi cần chuyển đổi hình ảnh của mình thành chuỗi Base64 để có thể gửi hình ảnh của mình đến máy chủ.

Có tệp JavaScript nào cho việc này không? Khác, làm thế nào tôi có thể chuyển đổi nó?


5
Hình ảnh của bạn đến từ đâu?
TJHeuvel


Câu trả lời:


182

Bạn có thể sử dụng HTML5 <canvas>cho nó:

Tạo một khung vẽ, tải hình ảnh của bạn vào đó và sau đó sử dụng toDataURL()để có được đại diện Base64 (thực ra, đó là một data:URL, nhưng nó chứa hình ảnh được mã hóa Base64).


3
toDataURLkiểm soát các cuộc gọi lại như done/fail/alwaystrường hợp của xhr không?
Jeroen

Chúng tôi có thể trích xuất 2 hoặc nhiều canvas dưới dạng một PNG không?
techie_28

140
Bạn có thể vui lòng tạo một jsbin hoặc ít nhất là viết một số mã ở đây?
vsync

9
Cách tiếp cận này thất bại trong trường hợp vi phạm CORS. Ngoài ra, giải pháp này nên giải quyết câu hỏi.
Revanth Kumar

Đây là gói
npm

851

Có nhiều cách tiếp cận bạn có thể chọn:

1. Cách tiếp cận: FileReader

Tải hình ảnh dưới dạng blob thông qua XMLHttpRequest và sử dụng API FileReader để chuyển đổi nó thành 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)
})

Ví dụ mã này cũng có thể được triển khai bằng API tìm nạp WHATWG :

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

Những cách tiếp cận sau:

  • thiếu hỗ trợ trình duyệt
  • có nén tốt hơn
  • cũng làm việc cho các loại tệp khác

Hỗ trợ trình duyệt:


2. Cách tiếp cận: Canvas

Tải hình ảnh vào một đối tượng hình ảnh, vẽ nó vào một khung vẽ không bị biến đổi và chuyển đổi khung vẽ trở lại thành 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)
  }
)

Chi tiết

Các định dạng đầu vào được hỗ trợ:

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

Các định dạng đầu ra được hỗ trợ:

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

Hỗ trợ trình duyệt:


3. Cách tiếp cận: Hình ảnh từ hệ thống tệp cục bộ

Nếu bạn muốn chuyển đổi hình ảnh từ hệ thống tệp người dùng, bạn cần thực hiện một cách tiếp cận khác. Sử dụng API FileReader :

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


56
Không hoạt động trong chrome đối với tôi: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.
DickieBoy

5
Chỉ trong trường hợp điều này làm bất kỳ ai khác gặp phải, thói quen này bao gồm tiêu đề "data: image / jpg; base64" trong chuỗi mà nó trả về, vì vậy bạn không cần phải thêm nó.
Chris Rae

1
Warnin2: một cái gì đó gây rối với nội dung. Ở đâu đó, có khả năng dữ liệu bị hỏng / bị thay đổi (mặc dù, có lẽ không nhiều), ít nhất điều đó xảy ra với tôi trên firefox 35 trên một số hình ảnh, base64 khác với Base64 mà php tạo ra trên cùng hình ảnh.
hanshenrik

1
Vâng đúng vậy. Một số dữ liệu có thể bị mất do chúng tôi thực sự vẽ hình ảnh thành một phần tử canvas ( developer.mozilla.org/en-US/docs/Web/API/ mẹo) và sau đó chuyển đổi nó thành dataURL ( developer.mozilla.org/en- US / docs / Web / API / HTMLCanvasEuity / Lỗi ).
HaNdTriX 6/03/2015

1
Cách tiếp cận: FileReader (2) hoạt động nhanh hơn so với tiếp cận Canvas. Đã thử nghiệm trên các bức ảnh lớn. Hy vọng nó sẽ hữu ích cho một số người.
Tối đa

83

Đoạn mã này có thể chuyển đổi tệp chuỗi, hình ảnh và thậm chí tệp video của bạn thành dữ liệu chuỗi 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>


3
Không chỉ là tuyệt vời, điều này cũng bỏ qua vấn đề nguồn gốc chéo! Với điều này, bạn có thể cho phép người dùng cung cấp hình ảnh hoặc hình ảnh của riêng họ từ một URL (vì Windows sẽ tự tải nó), vẽ chúng trên khung vẽ và làm việc với chúng trong khi vẫn có thể sử dụng .toDataURL (), v.v. Cảm ơn rất nhiều!
ElDoRado1239

Xin chào, làm thế nào điều này có thể được áp dụng cho một hình ảnh được tải từ một url từ xa mà không phải đối mặt với các vấn đề tên miền chéo? Cảm ơn
guthik

Điều này đôi khi hoạt động trong Chrome 78.0.3904.97, nhưng lần khác, nó bị sập tab.
Dshiz

28

Về cơ bản, nếu hình ảnh của bạn là

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

sau đó bạn có thể chuyển đổi nó như thế nào

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

5
Thật không may, điều này sẽ chỉ hoạt động đối với các hình ảnh cục bộ, nếu bạn thử sử dụng một hình ảnh từ xa (chọn một từ web) thì nó sẽ ghi vào bảng điều khiển (firefox): 'SecurityError: Hoạt động không an toàn'.
dùng2677034

1
Nó có thể hoạt động trên các hình ảnh khác nhưng phụ thuộc vào cài đặt CORS của trang web đó và phải được chỉ định là<img id='Img1' src='someurl' crossorigin='anonymous'>
Mike

Trên Firefox, bạn có thể tạm thời vô hiệu hóa bảo mật đó. Goto "about: config" và thay đổi thuộc tính "
Privacy.file_unique_origin

21

Đây là những gì tôi đã làm:

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

Và đây là cách bạn sử dụng nó

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

6
btoa là gì? :)
Alexander Mills


14

Tôi thấy rằng cách an toàn và đáng tin cậy nhất để làm điều đó là sử dụng FileReader().

Bản trình diễn: Hình ảnh cho 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>

6

Nếu bạn có một đối tượng tập tin, chức năng đơn giản này sẽ hoạt động:

function getBase64 (file, callback) {

    const reader = new FileReader();

    reader.addEventListener('load', () => callback(reader.result));

    reader.readAsDataURL(file);
}

Ví dụ sử dụng:

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



4

Hãy thử mã này:

Đối với một sự kiện thay đổi tải lên tập tin, gọi chức năng này:

$("#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();
}

Lưu trữ dữ liệu Base64 trong ẩn nộp để sử dụng.


1
Xin chào Ravi! Tôi thấy bạn là tương đối mới. Trừ khi người đăng ban đầu đặc biệt yêu cầu một giải pháp thư viện như jQuery, lodash, v.v., mọi người nên trả lời bằng cách sử dụng mức tối thiểu trần, trong trường hợp này là javascript đơn giản. Nếu bạn vẫn muốn đóng góp với jQuery, vui lòng làm cho nó rõ ràng trong mục của bạn :)
Carles Alcolea

3
uploadProfile(e) {

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

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

0

Chà, nếu bạn đang sử dụng Dojo Toolkit , nó cho chúng ta một cách trực tiếp để mã hóa hoặc giải mã thành Base64.

Thử cái này:

Để mã hóa một mảng byte bằng cách sử dụng dojox.encoding.base64:

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

Để giải mã một chuỗi được mã hóa Base64:

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

2
@DownVoter - Thưa bạn cũng tốt hơn để chỉ ra lỗi nếu bạn đang đánh dấu điều gì đó tiêu cực. để ai đó có thể cải thiện. theo như tôi hiểu về võ đường trong thư viện JavaScript thì nếu bạn được phép sử dụng võ đường, bạn hoàn toàn có thể sử dụng phương pháp này.
Vikash Pandey
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.