378 Stimmen

URL der Bilddaten in JavaScript abrufen?

Ich habe eine normale HTML-Seite mit einigen Bildern (nur normale <img /> HTML-Tags). Ich möchte ihren Inhalt erhalten, vorzugsweise base64-kodiert, ohne das Bild erneut herunterladen zu müssen (d. h. es wurde bereits vom Browser geladen, jetzt möchte ich den Inhalt).

Das würde ich gerne mit Greasemonkey und Firefox erreichen.

432voto

Matthew Crumley Punkte 98564

Nota: Dies funktioniert nur, wenn das Bild von der gleichen Domain wie die Seite stammt oder die crossOrigin="anonymous" Attribut und der Server unterstützt CORS. Außerdem erhalten Sie nicht die Originaldatei, sondern eine neu kodierte Version. Wenn das Ergebnis mit dem Original identisch sein soll, siehe Kaiidos Antwort .


Sie müssen ein Canvas-Element mit den richtigen Abmessungen erstellen und die Bilddaten mit dem Befehl drawImage Funktion. Dann können Sie die toDataURL Funktion, um eine data: url zu erhalten, die das base-64 kodierte Bild enthält. Beachten Sie, dass das Bild vollständig geladen sein muss, sonst erhalten Sie nur ein leeres (schwarzes, transparentes) Bild zurück.

Das würde in etwa so aussehen. Ich habe noch nie ein Greasemonkey-Skript geschrieben, daher müssen Sie den Code möglicherweise anpassen, damit er in dieser Umgebung läuft.

function getBase64Image(img) {
    // Create an empty canvas element
    var canvas = document.createElement("canvas");
    canvas.width = img.width;
    canvas.height = img.height;

    // Copy the image contents to the canvas
    var ctx = canvas.getContext("2d");
    ctx.drawImage(img, 0, 0);

    // Get the data-URL formatted image
    // Firefox supports PNG and JPEG. You could check img.src to
    // guess the original format, but be aware the using "image/jpg"
    // will re-encode the image.
    var dataURL = canvas.toDataURL("image/png");

    return dataURL.replace(/^data:image\/(png|jpg);base64,/, "");
}

Das Abrufen eines JPEG-formatierten Bildes funktioniert nicht mit älteren Versionen (etwa 3.5) von Firefox, wenn Sie das unterstützen wollen, müssen Sie die Kompatibilität überprüfen. Wenn die Kodierung nicht unterstützt wird, wird sie standardmäßig auf "image/png" gesetzt.

90voto

Kaiido Punkte 101425

Lange danach, aber keine der Antworten hier ist ganz richtig.

Beim Zeichnen auf einer Leinwand wird das übergebene Bild unkomprimiert und vormultipliziert.
Beim Export werden sie unkomprimiert oder mit einem anderen Algorithmus neu komprimiert und entmultipliziert.

Bei allen Browsern und Geräten treten bei diesem Vorgang unterschiedliche Rundungsfehler auf
(siehe Fingerabdruck auf Leinwand ).

Wenn man also eine base64-Version einer Bilddatei haben möchte, muss man Anfrage wieder (meistens kommt es aus dem Cache), aber diesmal als Blob.

Dann können Sie mit einem FileReader um sie entweder als ArrayBuffer oder als dataURL zu lesen.

function toDataURL(url, callback){
    var xhr = new XMLHttpRequest();
    xhr.open('get', url);
    xhr.responseType = 'blob';
    xhr.onload = function(){
      var fr = new FileReader();

      fr.onload = function(){
        callback(this.result);
      };

      fr.readAsDataURL(xhr.response); // async call
    };

    xhr.send();
}

toDataURL(myImage.src, function(dataURL){
  result.src = dataURL;

  // now just to show that passing to a canvas doesn't hold the same results
  var canvas = document.createElement('canvas');
  canvas.width = myImage.naturalWidth;
  canvas.height = myImage.naturalHeight;
  canvas.getContext('2d').drawImage(myImage, 0,0);

  console.log(canvas.toDataURL() === dataURL); // false - not same data
  });

<img id="myImage" src="https://dl.dropboxusercontent.com/s/4e90e48s5vtmfbd/aaa.png" crossOrigin="anonymous">
<img id="result">

88voto

MuniR Punkte 1333

Diese Funktion nimmt die URL und gibt das Bild als BASE64 zurück.

function getBase64FromImageUrl(url) {
    var img = new Image();

    img.setAttribute('crossOrigin', 'anonymous');

    img.onload = function () {
        var canvas = document.createElement("canvas");
        canvas.width =this.width;
        canvas.height =this.height;

        var ctx = canvas.getContext("2d");
        ctx.drawImage(this, 0, 0);

        var dataURL = canvas.toDataURL("image/png");

        alert(dataURL.replace(/^data:image\/(png|jpg);base64,/, ""));
    };

    img.src = url;
}

Nennen Sie es so: getBase64FromImageUrl("images/slbltxt.png")

32voto

Zaptree Punkte 3493

Eine modernere Version der kaiido-Antwort unter Verwendung von fetch würde lauten:

function toObjectUrl(url) {
  return fetch(url)
      .then((response)=> {
        return response.blob();
      })
      .then(blob=> {
        return URL.createObjectURL(blob);
      });
}

https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch

Bearbeiten: Wie in den Kommentaren darauf hingewiesen, wird dies ein Objekt url zurückgeben, die auf eine Datei in Ihrem lokalen System anstelle einer tatsächlichen DataURL zeigt, so dass je nach Ihrem Anwendungsfall dies möglicherweise nicht, was Sie benötigen.

Sie können sich die folgende Antwort ansehen, um fetch und eine aktuelle dataURL zu verwenden: https://stackoverflow.com/a/50463054/599602

9voto

argon Punkte 389

shiv / shim / sham

Wenn Ihr(e) Bild(er) bereits geladen sind (oder auch nicht), kann dieses "Werkzeug" sehr nützlich sein:

Object.defineProperty
(
    HTMLImageElement.prototype,'toDataURL',
    {enumerable:false,configurable:false,writable:false,value:function(m,q)
    {
        let c=document.createElement('canvas');
        c.width=this.naturalWidth; c.height=this.naturalHeight;
        c.getContext('2d').drawImage(this,0,0); return c.toDataURL(m,q);
    }}
);

aber warum?

Dies hat den Vorteil, dass die "bereits geladenen" Bilddaten verwendet werden, so dass keine zusätzliche Anforderung erforderlich ist. Darüber hinaus kann der Endbenutzer (Programmierer wie Sie) entscheiden, welche CORS und/oder mime-type y quality -Oder- Sie können diese Argumente/Parameter weglassen, wie es im Abschnitt MDN Spezifikation aquí .

Wenn Sie dieses JS geladen haben (bevor es benötigt wird), dann wird die Konvertierung in dataURL ist so einfach wie:

Beispiele

HTML

<img src="/yo.jpg" onload="console.log(this.toDataURL('image/jpeg'))">

JS

console.log(document.getElementById("someImgID").toDataURL());

GPU-Fingerprinting

Wenn Sie sich Sorgen um die "Genauigkeit" der Bits machen, können Sie dieses Werkzeug an Ihre Bedürfnisse anpassen, wie in der Antwort von @Kaiido beschrieben.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X