I want to know if there is any way to make a script using Javascript/jQuery to download (open a download dialog) a image so the browser won't just show it.
You need to use server-side scripting for this. Search on stackoverflow.
Alternately, your server might allow you to alter headers dynamically via configuration.
Place your downloadable images in a directory. Inside this directory, create a .htaccess
file with the following contents:
SetEnvIf Request_URI "([^/]+\.jpg)$" REQUESTED_IMAGE_BASENAME=$1
SetEnvIf Request_URI "([^/]+\.png)$" REQUESTED_IMAGE_BASENAME=$1
Header set Content-Disposition "attachment; filename=\"%{REQUESTED_IMAGE_BASENAME}e\"" env=REQUESTED_IMAGE_BASENAME
Test Request:
HEAD /test/Water%20lilies.jpg HTTP/1.1
Host: localhost
Test Response:
HTTP/1.1 200 OK
Date: Sat, 23 Jul 2011 09:03:52 GMT
Server: Apache/2.2.17 (Win32)
Last-Modified: Thu, 23 Aug 2001 14:00:00 GMT
ETag: "26000000017df3-14752-38c32e813d800"
Accept-Ranges: bytes
Content-Length: 83794
Content-Disposition: attachment; filename="Water lilies.jpg"
Content-Type: image/jpeg
You can use the HTML5 download
attribute on anchors:
<p>Example 1<br>
<a href="http://dummyimage.com/600x400/000/fff.png" download>Download this image</a></p>
<p>Example 2<br>
<a href="http://dummyimage.com/600x400/000/fff.png" download="alternate-filename.png"><img
src="http://dummyimage.com/150x100/000/fff.png"></a></p>
I have come up with pure JavaScript way to force download of image, with the following restrictions:
The above restrictions (especially the third) more or less renders this useless but still, the "core" idea is working and hopefully at some point in the future it will be possible to determine file name then it will become much more useful.
Here is the code:
function DownloadImage(imageURL) {
var oImage = document.getElementById(imageURL);
var canvas = document.createElement("canvas");
document.body.appendChild(canvas);
if (typeof canvas.getContext == "undefined" || !canvas.getContext) {
alert("browser does not support this action, sorry");
return false;
}
try {
var context = canvas.getContext("2d");
var width = oImage.width;
var height = oImage.height;
canvas.width = width;
canvas.height = height;
canvas.style.width = width + "px";
canvas.style.height = height + "px";
context.drawImage(oImage, 0, 0, width, height);
var rawImageData = canvas.toDataURL("image/png;base64");
rawImageData = rawImageData.replace("image/png", "image/octet-stream");
document.location.href = rawImageData;
document.body.removeChild(canvas);
}
catch (err) {
document.body.removeChild(canvas);
alert("Sorry, can't download");
}
return true;
}
As you can see, the trick is drawing the image into canvas
object, get the raw binary data of the image then force download by using image/octet-stream
mime type and changing the browser location.
Usage sample follows as well.
HTML:
<image id="myimage" src="Penguins.jpg" />
<button type="btnDownload" rel="myimage">Download</button>
JavaScript:
window.onload = function() {
var arrButtons = document.getElementsByTagName("button");
for (var i = 0; i < arrButtons.length; i++) {
var oButton = arrButtons[i];
var sRelatedImage = oButton.getAttribute("rel");
if (sRelatedImage && sRelatedImage.length > 0) {
oButton.onclick = function() {
HandleRelatedImage(this, sRelatedImage);
}
}
}
};
function HandleRelatedImage(oButton, sRelatedImage) {
var oImage = document.getElementById(sRelatedImage);
if (!oImage) {
alert("related image '" + sRelatedImage + "' does not exist");
return false;
}
return DownloadImage(sRelatedImage);
}
This allows to "attach" download button to every existing image by assigning the rel
attribute of the button to the image ID - the code will do the rest and attach the actual click events.
Due to the same origin policy can't post live example at jsFiddle - they're using "sandbox" domain to execute the scripts.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With