Bild in Base64 konvertieren

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

Ich möchte das Bild in base64 erhalten, sobald der Benutzer dies ausgewählt hat (bevor er das Formular abschickt).

Etwas wie :

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

Ich habe über die Datei-API und andere Dinge gelesen und möchte eine einfache und browserübergreifende Lösung (IE6 / IE7 offensichtlich ausgeschlossen).

Jede Hilfe dankbar.

bombastisch
quelle
1
Und was haben Sie über die HTML5-Datei-API nicht verstanden? Was hast du versucht? Was hat nicht funktioniert?
epascarello
@epascarello sie werden nicht vollständig unterstützt tatsächlich caniuse.com/#feat=fileapi Ich brauche eine Lösung , vor allem, weil Android-Versionen weiterhin verwendet werden (alte Versionen) sowie für alte iOS-Versionen, und ich möchte auch IE9 einbeziehen, die wird immer noch viel benutzt: P
bombastisch
eine Problemumgehung für was? Was versuchst du mit der Datei zu machen? base64file()- Ist das ein Plugin?
David Hellsing
@ David Ich möchte nur die base64-Datei erhalten, sobald der Benutzer die Datei von seinem PC ausgewählt hat. Base64file () ist nur ein Beispiel
bombastisch
1
@epascarello ja und das war genau meine Frage, wie man alle Browser unterstützt: D
bombastisch

Antworten:

208

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: Ein Base64-codiertes Bild (String) 4/3 der Größe der Originalbilddaten)

Überprüfen Sie diese Antwort auf das Hochladen mehrerer Bilder .

Browserunterstützung: http://caniuse.com/#search=file%20api
Weitere Informationen hier: https://developer.mozilla.org/en-US/docs/Web/API/FileReader

Roko C. Buljan
quelle
2
Ja, danke, also kann ich sehen, dass der Dateireader nicht vollständig unterstützt wird. Wie kann ich dafür sorgen, dass auch alte Android- / iOS-Geräte unterstützt werden?
bombastisch
1
Gibt es noch andere Browser? xD
RicardoE
Das war wirklich ordentlicher Code für die Konvertierung von Bild zu Base64. Kann ich diesen in Javascript wieder in Bild konvertieren? Ich habe bereits Base64-Codierungsdecodierung verwendet, habe aber keine Ahnung von Bildkonvertierungen.
The Coder
@TheCoder Sie können es als base64-Zeichenfolge direkt in img src einfügen. Um Bilddaten daraus zu erhalten, verwenden Sie den Canvas-Kontext.
Qwerty
1
@bombastic Ich habe JS verwendet, um sowohl iOS- als auch Android-Apps auf beiden Plattformen zu erstellen. Sie haben einwandfrei funktioniert. Das iOS ist normal und auf Android, ich hatte einen nativen Code benötigt, um die Erlaubnis zur Galerie zu bekommen ...
Osman Gani Khan Masum
36

Genau das, was Sie brauchen :) Sie können zwischen Callback-Version und Promise-Version wählen. Beachten Sie, dass Versprechen im IE nur mit Promise polyfill lib funktionieren. Sie können diesen Code einmal auf einer Seite einfügen, und diese Funktion wird in allen Ihren Dateien angezeigt.

Das Loadend-Ereignis wird ausgelöst, wenn der Fortschritt beim Laden einer Ressource gestoppt wurde (z. B. nachdem "Fehler", "Abbruch" oder "Laden" ausgelöst wurden).

Rückrufversion

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

Versprich Version

    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/>
Alex Nikulin
quelle
7

In diesem Fall ist es nützlich, mit dem verzögerten Objekt zu arbeiten und das Versprechen zurückzugeben:

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

Und die obige Funktion könnte folgendermaßen verwendet werden:

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

Oder in Ihrem Fall:

$(input).on('change',function(){
  readImage($(this)).done(function(base64Data){ alert(base64Data); });
});
Vasyl Senko
quelle
Ich brauchte das wirklich, ich meine die verzögerte, da ich die base64 zur aufrufenden Methode zurückbringe. Ich möchte wissen, ob Ihre Lösung in allen Browsern funktioniert.
Thameem
7
<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);
}
Vasyl Petrov
quelle
1
'file' wird deklariert, aber sein Wert wird niemals in der Funktion getBaseUrl () gelesen.
Biranchi
@Biranchi filewird in der letzten Zeile verwendetreader.readAsDataURL(file);
Achim