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


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


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


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>


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

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

6
Was ist Btoa? :)
Alexander Mills


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>

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



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.


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

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

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
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.