Wie kann ich ein Bild mit JavaScript in einen Base64-String konvertieren?

Antworten:

182

Sie können den HTML5 <canvas>dafür verwenden:

Erstellen Sie eine Zeichenfläche, laden Sie Ihr Bild hinein und verwenden Sie dann toDataURL(), um die Base64-Darstellung abzurufen (tatsächlich handelt es sich um eine data:URL, die jedoch das Base64-codierte Bild enthält).

DiebMaster
quelle
3
Gibt toDataURLdie Kontrolle über die Rückrufe, wie done/fail/alwaysdies bei xhr der Fall ist?
Jeroen
Können wir 2 oder mehr Canvas als einzelnes PNG extrahieren?
Techie_28
140
Kannst du bitte einen jsbin machen oder zumindest hier einen Code schreiben?
vsync
9
Dieser Ansatz schlägt bei einer CORS-Verletzung fehl. Abgesehen davon sollte diese Lösung die Frage beantworten.
Revanth Kumar
Hier ist npm Paket dafür
user3517175
851

Es gibt mehrere Ansätze, aus denen Sie auswählen können:

1. Ansatz: FileReader

Laden Sie das Bild als Blob über XMLHttpRequest und konvertieren Sie es mit der FileReader-API in eine 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)
})

Dieses Codebeispiel könnte auch mithilfe der WHATWG- Abruf-API implementiert werden :

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

Diese Ansätze:

  • mangelnde Browserunterstützung
  • bessere Komprimierung haben
  • arbeiten auch für andere Dateitypen

Browser-Unterstützung:


2. Ansatz: Leinwand

Laden Sie das Bild in ein Bildobjekt, malen Sie es auf eine nicht verschmutzte Leinwand und konvertieren Sie die Leinwand zurück in eine 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)
  }
)

Im Detail

Unterstützte Eingabeformate:

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

Unterstützte Ausgabeformate:

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

Browser-Unterstützung:


3. Vorgehensweise: Bilder aus dem lokalen Dateisystem

Wenn Sie Bilder aus dem Dateisystem des Benutzers konvertieren möchten, müssen Sie einen anderen Ansatz wählen. Verwenden Sie die 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)" />

HaNdTriX
quelle
56
Ich arbeite nicht in Chrom für mich: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
Nur für den Fall, dass dies andere auslöst, enthält diese Routine den Header "data: image / jpg; base64" in der zurückgegebenen Zeichenfolge, sodass Sie diesen nicht anhängen müssen.
Chris Rae
1
Warnin2: Etwas bringt den Inhalt durcheinander. Irgendwo auf dem Weg besteht die Möglichkeit, dass die Daten beschädigt / verändert werden (obwohl, vielleicht nicht viel), zumindest bei Firefox 35 auf einigen Bildern, unterscheidet sich die Base64 von der Base64, die PHP auf derselben erstellt Bild.
Hanshenrik
1
Ja, das ist richtig. Einige Daten können verloren gehen, da wir das Bild tatsächlich in ein Canvas-Element ( developer.mozilla.org/en-US/docs/Web/API/… ) zeichnen und es dann in eine dataURL ( developer.mozilla.org/en- ) konvertieren. US / docs / Web / API / HTMLCanvasElement /… ).
HaNdTriX
1
Vorgehensweise: FileReader (2) funktioniert schneller als die Vorgehensweise bei Canvas. Getestet auf großen Fotos. Hoffe, es wird für jemanden hilfreich sein.
Max
83

Dieses Snippet kann Ihre Zeichenfolge, Ihr Bild und sogar Ihre Videodatei in Base64-Zeichenfolgendaten konvertieren.

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

Carles Alcolea
quelle
3
Es ist nicht nur großartig, dies umgeht auch das Crossdomain-Ursprungsproblem! Auf diese Weise können Sie Benutzern erlauben, ihre eigenen Bilder oder Bilder von einer URL bereitzustellen (da Windows sie selbst abruft), sie auf die Leinwand zu zeichnen und mit ihnen zu arbeiten, während Sie weiterhin .toDataURL () usw. verwenden können. Vielen Dank!
ElDoRado1239
Hallo, wie kann dies auf ein Bild angewendet werden, das von einer Remote-URL geladen wurde, ohne dass domänenübergreifende Probleme auftreten? Danke
guthik
Dies funktioniert manchmal in Chrome 78.0.3904.97, aber manchmal stürzt die Registerkarte ab.
Dshiz
28

Grundsätzlich, wenn Ihr Bild ist

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

dann kannst du es gerne umwandeln

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();
mehmet mecek
quelle
5
Leider funktioniert dies nur für lokale Images. Wenn Sie versuchen, ein Remote-Image zu verwenden (wählen Sie eines aus dem Web aus), wird dies in die (Firefox-) Konsole geschrieben: 'SecurityError: Der Vorgang ist unsicher'.
user2677034
1
Es kann auf anderen Bildern funktionieren, hängt jedoch von den CORS-Einstellungen dieser Site ab und muss als<img id='Img1' src='someurl' crossorigin='anonymous'>
Mike
In Firefox können Sie diese Sicherheit vorübergehend deaktivieren. Gehen Sie zu "about: config" und ändern Sie die Eigenschaft "privacy.file_unique_origin" in false
Manuel Romeiro
21

Folgendes habe ich getan:

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

Und so verwenden Sie es

base64( $('input[type="file"]'), function(data){
  console.log(data.base64)
})
James Harrington
quelle
6
Was ist Btoa? :)
Alexander Mills
4
a = ASCII und b = Binary stackoverflow.com/questions/33854103/…
James Harrington
14

Ich fand, dass der sicherste und zuverlässigste Weg, dies zu tun, die Verwendung ist FileReader().

Demo: Image zu 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>
Jonathana
quelle
6

Wenn Sie ein Dateiobjekt haben, funktioniert diese einfache Funktion:

function getBase64 (file, callback) {

    const reader = new FileReader();

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

    reader.readAsDataURL(file);
}

Anwendungsbeispiel:

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
});
Shubham
quelle
5

Sie könnten FileAPI verwenden , aber es wird so gut wie nicht unterstützt.

Artem Tikhomirov
quelle
4

Versuchen Sie diesen Code:

Rufen Sie für ein Änderungsereignis zum Hochladen von Dateien diese Funktion auf:

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

Speichern Sie Base64-Daten in versteckten Dateien, um sie zu verwenden.

Ravi Polara
quelle
1
Hallo Ravi! Ich sehe, du bist relativ neu. Sofern das Originalplakat nicht ausdrücklich nach einer Bibliothekslösung wie jQuery, lodash usw. fragt, ist es für alle besser, mit dem bloßen Minimum zu antworten, in diesem Fall mit einfachem Javascript. Wenn Sie immer noch mit jQuery beitragen möchten, machen Sie dies bitte in Ihrem Eintrag deutlich :)
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);
}
Mahedi Hasan Durjoy
quelle
0

Wenn Sie Dojo Toolkit verwenden , können wir direkt in Base64 codieren oder decodieren.

Versuche dies:

So codieren Sie ein Array von Bytes mit dojox.encoding.base64:

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

So dekodieren Sie eine Base64-codierte Zeichenfolge:

var bytes = dojox.encoding.base64.decode(str);
Vikash Pandey
quelle
2
@DownVoter - Lieber, es ist besser, auf Fehler hinzuweisen, auch wenn Sie etwas Negatives markieren. damit sich jemand verbessern kann. Soweit ich Dojo auch in einer JavaScript-Bibliothek verstehe, können Sie diesen Ansatz definitiv verwenden, wenn Sie Dojo verwenden dürfen.
Vikash Pandey