Obtener datos de imagen en JavaScript?


Tengo una página HTML regular con algunas imágenes (solo etiquetas HTML regulares <img />). Me gustaría obtener su contenido, base64 codificado preferiblemente, sin la necesidad de volver a descargar la imagen (es decir. ya está cargado por el navegador, así que ahora quiero el contenido).

Me encantaría lograr eso con Greasemonkey y Firefox.

Author: Volker E., 2009-06-01

6 answers

Nota: Esto solo funciona si la imagen es del mismo dominio que la página, o tiene el atributo crossOrigin="anonymous" y el servidor admite CORS. Tampoco te dará el archivo original, sino una versión codificada nuevamente. Si necesita que el resultado sea idéntico al original, vea La respuesta de Kaiido.


Necesitará crear un elemento canvas con las dimensiones correctas y copiar los datos de la imagen con la función drawImage. Luego puede usar la función toDataURL para obtener un dato: url que tiene la imagen codificada en base-64. Tenga en cuenta que la imagen debe estar completamente cargada, o simplemente obtendrá una imagen vacía (negra, transparente).

Sería algo así. Nunca he escrito un script de Greasemonkey, por lo que es posible que deba ajustar el código para que se ejecute en ese entorno.

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

Obtener una imagen con formato JPEG no funciona en versiones anteriores (alrededor de 3.5) de Firefox, por lo que si desea admitir eso, deberá verificar la compatibilidad. Si la codificación no es soportado, por defecto será "image / png".

 382
Author: Matthew Crumley,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:03:09

Esta función toma la URL y luego devuelve la imagen 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;
}

Llámalo así : getBase64FromImageUrl("images/slbltxt.png")

 69
Author: MuniR,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-12-10 18:18:36

Viene mucho después, pero ninguna de las respuestas aquí son del todo correctas.

Cuando se dibuja en un lienzo, la imagen pasada se descomprime + todo se pre-multiplica.
Cuando se exporta, se descomprime o recomprime con un algoritmo diferente, y se descomprime.

Todos los navegadores y dispositivos tendrán diferentes errores de redondeo que ocurren en este proceso
(ver Huellas dactilares de lienzo ).

Así que si uno quiere una versión base64 de un archivo de imagen, tienen que request it again (most of the time it will come from cache) but this time as a Blob.

Entonces puede usar un FileReader para leerlo como un ArrayBuffer, o como un 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
Author: Kaiido,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-06-17 18:22:17

Además de la respuesta de Matthew, me gustaría decir esa imagen.ancho e imagen.altura devuelve el tamaño mostrado de la imagen (y recorta la imagen al dibujarla en el lienzo)

Utilice naturalWidth y naturalHeight en su lugar, que utiliza la imagen de tamaño real.

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

 22
Author: cube45,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-06-11 16:00:04

Una versión más moderna de la respuesta de kaiido usando fetch sería:

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
Author: Zaptree,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
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>
Aquí está el Ejemplo del Violín de Trabajo: - subir y obtener datos de imagen
 0
Author: Parth Raval,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-12-15 05:51:35