Obtenir des données d'image en JavaScript?

J'ai une page HTML régulière avec quelques images (juste des balises HTML <img /> régulières). Je voudrais obtenir leur contenu, codé en base64 de préférence, sans avoir besoin de télécharger à nouveau l'image (ie. il est déjà chargé par le navigateur, alors maintenant je veux le contenu).

J'aimerais y parvenir avec Greasemonkey et Firefox.

301
demandé sur Volker E. 2009-06-01 12:43:42

6 réponses

Remarque: {[6] } cela ne fonctionne que si l'image provient du même domaine que la page, ou a l'attribut crossOrigin="anonymous" et le serveur prend en charge CORS. Il ne va pas non plus vous donner le fichier original, mais une version ré-encodée. Si vous avez besoin que le résultat soit identique à l'original, consultez la réponse de Kaiido .


Vous devrez créer un élément canvas avec les dimensions correctes et copier les données d'image avec la fonction drawImage. Ensuite, vous pouvez utiliser la fonction toDataURL pour obtenir une donnée: url qui a l'image codée en base 64. Notez que l'image doit être complètement chargée, sinon vous récupérerez simplement une image vide (noire, transparente).

Ce serait quelque chose comme ça. Je n'ai jamais écrit de script Greasemonkey, donc vous devrez peut-être ajuster le code pour l'exécuter dans cet environnement.

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

Obtenir une image au format JPEG ne fonctionne pas sur les anciennes versions (environ 3.5) de Firefox, donc si vous voulez prendre en charge cela, vous devrez vérifier la compatibilité. Si le codage n'est pas pris en charge, il sera par défaut à "image/png".

382
répondu Matthew Crumley 2017-05-23 12:03:09

Cette fonction prend L'URL puis renvoie L'image BASE64

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

Appelez-le comme ceci : getBase64FromImageUrl("images/slbltxt.png")

69
répondu MuniR 2015-12-10 18:18:36

Venant bien après, mais aucune des réponses ici n'est tout à fait correcte.

Lorsqu'elle est dessinée sur un canevas, l'image passée est décompressée + toutes pré-multipliées.
Lorsqu'il est exporté, il est décompressé ou recompressé avec un algorithme différent, et non multiplié.

Tous les navigateurs et périphériques auront des erreurs d'arrondi différentes qui se produisent dans ce processus
(voir Canvas fingerprinting).

Donc, si l'on veut une version base64 d'un fichier image, il faut request it again (la plupart du temps il viendra du cache) mais cette fois comme un Blob.

Ensuite, vous pouvez utiliser un FileReader pour le lire soit comme ArrayBuffer, soit comme dataURL.

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">
32
répondu Kaiido 2018-06-17 18:22:17

En plus de la réponse de matthew, j'aimerais dire cette image.la largeur et de l'image.hauteur retourne la taille affichée de l'image (et recadre l'image lorsque vous la dessinez sur le canevas)

Utilisez naturalWidth et naturalHeight à la place, qui utilise l'image en taille réelle.

Voir http://www.whatwg.org/specs/web-apps/current-work/multipage/edits.html#dom-img-naturalwidth

22
répondu cube45 2014-06-11 16:00:04

Une version plus moderne de la réponse de kaiido en utilisant fetch serait:

function toDataURL(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

10
répondu Zaptree 2017-07-21 21:36:06

function encodeImageFileAsURL(cb) {
    return function() {
        var file = this.files[0];
        var reader = new FileReader();
        reader.onloadend = function() {
            cb(reader.result);
        }
        reader.readAsDataURL(file);
    }
}

$('#inputFileToLoad').change(encodeImageFileAsURL(function(base64Img) {
    $('.output')
        .find('textarea')
        .val(base64Img)
        .end()
        .find('a')
        .attr('href', base64Img)
        .text(base64Img)
        .end()
        .find('img')
        .attr('src', base64Img);
}));
@import url('//netdna.bootstrapcdn.com/bootstrap/3.1.0/css/bootstrap.min.css'); body{ padding: 20px; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h2>Input</h2>
<form class="input-group" id="img2b64">
    <input id="inputFileToLoad" type="file" onchange="encodeImageFileAsURL();" />
</form>
<hr>
Voici un exemple de violon qui fonctionne: - Télécharger et obtenir des données D'Image
0
répondu Parth Raval 2017-12-15 05:51:35