Navegador / HTML Forzar la descarga de la imagen desde src = " datos: imagen / jpeg; base64…"


Estoy generando una imagen en el lado del cliente y la muestro con HTML de esta manera:

<img src="data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAMCAgICAgM...."/>

Quiero ofrecer la posibilidad de descargar la Imagen generada.

¿Cómo puedo darme cuenta de que el navegador está abriendo un diálogo de guardado de archivos (o simplemente descargar la imagen como chrome o firefox a la carpeta de descargas haría) que permite al usuario guardar la imagen sin hacer clic derecho y guardar como en la imagen?

Preferiría una solución sin interacción con el servidor. Así que soy consciente de que sería posible si primero subo la Imagen y luego inicio la descarga.

Muchas Gracias!

Author: alex, 2012-05-07

4 answers

Simplemente reemplace image/jpeg por application/octet-stream. El cliente no reconocería la URL como un recurso en línea y solicitaría un diálogo de descarga.

Una solución simple de JavaScript sería:

//var img = reference to image
var url = img.src.replace(/^data:image\/[^;]+/, 'data:application/octet-stream');
window.open(url);
// Or perhaps: location.href = url;
// Or even setting the location of an <iframe> element, 

Otro método es usar un URI blob::

var img = document.images[0];
img.onclick = function() {
    // atob to base64_decode the data-URI
    var image_data = atob(img.src.split(',')[1]);
    // Use typed arrays to convert the binary data to a Blob
    var arraybuffer = new ArrayBuffer(image_data.length);
    var view = new Uint8Array(arraybuffer);
    for (var i=0; i<image_data.length; i++) {
        view[i] = image_data.charCodeAt(i) & 0xff;
    }
    try {
        // This is the recommended method:
        var blob = new Blob([arraybuffer], {type: 'application/octet-stream'});
    } catch (e) {
        // The BlobBuilder API has been deprecated in favour of Blob, but older
        // browsers don't know about the Blob constructor
        // IE10 also supports BlobBuilder, but since the `Blob` constructor
        //  also works, there's no need to add `MSBlobBuilder`.
        var bb = new (window.WebKitBlobBuilder || window.MozBlobBuilder);
        bb.append(arraybuffer);
        var blob = bb.getBlob('application/octet-stream'); // <-- Here's the Blob
    }

    // Use the URL object to create a temporary URL
    var url = (window.webkitURL || window.URL).createObjectURL(blob);
    location.href = url; // <-- Download!
};

Documentación pertinente

 101
Author: Rob W,
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-11-09 08:03:30

Puede usar el atributo download en una etiqueta a...

<a href="data:image/jpeg;base64,/9j/4AAQSkZ..." download="filename.jpg"></a>

Ver más: https://developer.mozilla.org/en/HTML/element/a#attr-download

 78
Author: Bruce Aldridge,
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
2012-06-13 23:24:45

Supongo que se necesita una etiqueta img como hija de una etiqueta a, de la siguiente manera:

<a download="YourFileName.jpeg" href="data:image/jpeg;base64,iVBO...CYII=">
    <img src="data:image/jpeg;base64,iVBO...CYII="></img>
</a>

O

<a download="YourFileName.jpeg" href="/path/to/OtherFile.jpg">
    <img src="/path/to/OtherFile.jpg"></img>
</a>

Solo usar la etiqueta a como se explica en #15 no funcionó para mí con la última versión de Firefox y Chrome, pero poner los mismos datos de imagen en a.href y img.las etiquetas src funcionaron para mí.

Desde JavaScript se podría generar así:

var data = canvas.toDataURL("image/jpeg");

var img = document.createElement('img');
img.src = data;

var a = document.createElement('a');
a.setAttribute("download", "YourFileName.jpeg");
a.setAttribute("href", data);
a.appendChild(img);

var w = open();
w.document.title = 'Export Image';
w.document.body.innerHTML = 'Left-click on the image to save it.';
w.document.body.appendChild(a);
 13
Author: user3521208,
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-04-10 20:47:58

Echa un vistazo a FileSaver.js . Proporciona una práctica función saveAs que se encarga de la mayoría de las peculiaridades específicas del navegador.

 2
Author: jesal,
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-07-09 22:40:01