Chuyển đổi hình ảnh sang Base64


85
<input type="file" id="asd"/>

Tôi muốn lấy hình ảnh trong base64 khi người dùng đã chọn (trước khi gửi biểu mẫu)

Cái gì đó như :

$(input).on('change',function(){
  var data = $(this).val().base64file(); // it is not a plugin is just an example
  alert(data);
});

Tôi đã đọc về API tệp và các nội dung khác, tôi muốn có một giải pháp đơn giản và đa trình duyệt (rõ ràng là IE6 / IE7 bị loại trừ)

Bất kỳ sự giúp đỡ đánh giá cao cảm ơn.


1
Và bạn chưa hiểu gì về HTML5 File api? Bạn đã thử những gì? Điều gì đã không hoạt động?
epascarello

@epascarello họ không được hỗ trợ đầy đủ thực sự caniuse.com/#feat=fileapi tôi cần một công việc xung quanh, đặc biệt là nguyên nhân gây ra các phiên bản Android vẫn được sử dụng (phiên bản cũ) cũng như cho các phiên bản iOS cũ, và tôi cũng muốn tham gia IE9 mà vẫn được sử dụng rất nhiều: P
khoa trương

một giải pháp cho những gì? Bạn đang cố gắng làm gì với tệp? base64file()- đó có phải là một plugin không?
David Hellsing,

@David, tôi chỉ muốn lấy tệp base64 sau khi người dùng chọn tệp từ máy tính của anh ấy, base64file () chỉ là một ví dụ
khoa trương

1
@epascarello vâng và đó chính xác là câu hỏi của tôi, làm thế nào để hỗ trợ tất cả các trình duyệt: D
khoa trương

Câu trả lời:


210

function readFile() {
  
  if (this.files && this.files[0]) {
    
    var FR= new FileReader();
    
    FR.addEventListener("load", function(e) {
      document.getElementById("img").src       = e.target.result;
      document.getElementById("b64").innerHTML = e.target.result;
    }); 
    
    FR.readAsDataURL( this.files[0] );
  }
  
}

document.getElementById("inp").addEventListener("change", readFile);
<input id="inp" type='file'>
<p id="b64"></p>
<img id="img" height="150">

( PS: Hình ảnh được mã hóa base64 (Chuỗi) 4/3 kích thước của dữ liệu hình ảnh gốc)

Kiểm tra câu trả lời này để tải lên nhiều hình ảnh .

Hỗ trợ trình duyệt: http://caniuse.com/#search=file%20api
Thông tin thêm tại đây: https://developer.mozilla.org/en-US/docs/Web/API/FileReader


2
vâng, cảm ơn bạn, vì vậy thực sự tôi có thể thấy Trình đọc tệp không được hỗ trợ đầy đủ, làm thế nào tôi có thể tạo các thiết bị Android / iOS cũ cũng hỗ trợ tương tự?
khoa trương

1
có trình duyệt nào khác không? xD
RicardoE

Đó là mã thực sự gọn gàng để chuyển đổi hình ảnh sang base64 .. Tôi có thể chuyển đổi mã này trở lại thành hình ảnh trong javascript không? Tôi đã sử dụng giải mã mã hóa base64 trước đây, nhưng không có bất kỳ ý tưởng nào về chuyển đổi hình ảnh ..
The Coder

@TheCoder Bạn có thể đặt nó ngay vào img src dưới dạng chuỗi base64, để lấy dữ liệu hình ảnh ra khỏi nó, hãy sử dụng ngữ cảnh canvas.
Qwerty

1
@bombastic Tôi đã sử dụng JS để xây dựng cả ứng dụng iOS và android trên cả hai nền tảng mà chúng hoạt động tốt. IOS là bình thường và trên android, tôi đã cần một số mã nguồn gốc để có được sự cho phép để bộ sưu tập ...
Osman Gani Khan Masum

36

Chính xác những gì bạn cần :) Bạn có thể chọn phiên bản gọi lại hoặc phiên bản Promise. Lưu ý rằng Promise sẽ chỉ hoạt động trong IE với Promise polyfill lib. Bạn có thể đặt mã này một lần trên một trang và chức năng này sẽ xuất hiện trong tất cả các tệp của bạn.

Sự kiện loadend được kích hoạt khi tiến trình đã dừng khi tải tài nguyên (ví dụ: sau khi "lỗi", "hủy bỏ" hoặc "tải" đã được gửi đi)

Phiên bản gọi lại

        File.prototype.convertToBase64 = function(callback){
                var reader = new FileReader();
                reader.onloadend = function (e) {
                    callback(e.target.result, e.target.error);
                };   
                reader.readAsDataURL(this);
        };

        $("#asd").on('change',function(){
          var selectedFile = this.files[0];
          selectedFile.convertToBase64(function(base64){
               alert(base64);
          }) 
        });

Phiên bản hứa hẹn

    File.prototype.convertToBase64 = function(){
         return new Promise(function(resolve, reject) {
                var reader = new FileReader();
                reader.onloadend = function (e) {
                    resolve({
                      fileName: this.name,
                      result: e.target.result, 
                      error: e.target.error
                    });
                };   
                reader.readAsDataURL(this);
        }.bind(this)); 
    };

    FileList.prototype.convertAllToBase64 = function(regexp){
      // empty regexp if not set
      regexp = regexp || /.*/;
      //making array from FileList
      var filesArray = Array.prototype.slice.call(this);
      var base64PromisesArray = filesArray.
           filter(function(file){
             return (regexp).test(file.name)
           }).map(function(file){
             return file.convertToBase64();
           });
      return Promise.all(base64PromisesArray);
    };

    $("#asd").on('change',function(){
      //for one file
      var selectedFile = this.files[0];
      selectedFile.convertToBase64().
          then(function(obj){
            alert(obj.result);
          });
      });
      //for all files that have file extention png, jpeg, jpg, gif
      this.files.convertAllToBase64(/\.(png|jpeg|jpg|gif)$/i).then(function(objArray){
            objArray.forEach(function(obj, i){
                  console.log("result[" + obj.fileName + "][" + i + "] = " + obj.result);
            });
      });
    })

html

<input type="file" id="asd" multiple/>

8
<input type="file" onchange="getBaseUrl()">
function getBaseUrl ()  {
    var file = document.querySelector('input[type=file]')['files'][0];
    var reader = new FileReader();
    var baseString;
    reader.onloadend = function () {
        baseString = reader.result;
        console.log(baseString); 
    };
    reader.readAsDataURL(file);
}

1
'tệp' được khai báo nhưng giá trị của nó không bao giờ được đọc bên trong hàm getBaseUrl ().
Biranchi

@Biranchi fileđược sử dụng ở dòng cuối cùngreader.readAsDataURL(file);
Achim

7

Sẽ rất hữu ích khi làm việc với Đối tượng bị trì hoãn trong trường hợp này và trả về lời hứa:

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

Và hàm trên có thể được sử dụng theo cách này:

var inputElement = $("input[name=file]");
readImage(inputElement).done(function(base64Data){
    alert(base64Data);
});

Hoặc trong trường hợp của bạn:

$(input).on('change',function(){
  readImage($(this)).done(function(base64Data){ alert(base64Data); });
});

tôi thực sự cần điều này, tôi có nghĩa là bị hoãn lại vì tôi đang trả về phương thức gọi base64. Tôi muốn biết liệu giải pháp của bạn có hoạt động trên tất cả các trình duyệt không?
Thameem
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.