I came up with a clean JavaScript method for forcing an image to download with the following limitations:
- Using HTML5 doesn't work like that at all in IE browsers prior to IE9.
- In IE (even 9) limited to very small images, due to URL length limitations.
- The name of the image (when saved on the machine) cannot be defined in the code, in Chrome it will just โdownloadโ without an extension, and in Firefox it will look like a jibberish line with the extension โ.partโ - in any case, the user will have to rename the file to make it usable.
- You can only upload images in the same domain - the same origin policy.
The above limitations (especially the third one) more or less make it useless, but nevertheless, the "main" idea works and, I hope, at some point in the future it will be possible to determine the file name, 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 draws the image into a canvas object, receives raw binary image data, and then is forced to load using the mime image/octet-stream and changing the location of the browser.
The following is an example of use.
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 you to "attach" the download button to each existing image by assigning the button rel attribute to the image identifier - the code will do the rest and attach the actual click events.
Due to the same origin policy, you cannot publish a live example in jsFiddle - they use the sandbox domain to execute scripts.
Shadow Wizard Feb 06 2018-12-12T00: 00Z
source share