I have a regular HTML page with some images (just regular <img />
HTML tags). I'd like to get their content, base64 encoded preferably, without the need to redownload the image (ie. it's already loaded by the browser, so now I want the content).
I'd love to achieve that with Greasemonkey and Firefox.
This question is related to
javascript
image
firefox
greasemonkey
base64
This Function takes the URL then returns the 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;
}
Call it like this :
getBase64FromImageUrl("images/slbltxt.png")
This is all you need to read.
https://developer.mozilla.org/en-US/docs/Web/API/FileReader/readAsBinaryString
var height = 200;
var width = 200;
canvas.width = width;
canvas.height = height;
var ctx = canvas.getContext('2d');
ctx.strokeStyle = '#090';
ctx.beginPath();
ctx.arc(width/2, height/2, width/2 - width/10, 0, Math.PI*2);
ctx.stroke();
canvas.toBlob(function (blob) {
//consider blob is your file object
var reader = new FileReader();
reader.onload = function () {
console.log(reader.result);
}
reader.readAsBinaryString(blob);
});
Coming long after, but none of the answers here are entirely correct.
When drawn on a canvas, the passed image is uncompressed + all pre-multiplied.
When exported, its uncompressed or recompressed with a different algorithm, and un-multiplied.
All browsers and devices will have different rounding errors happening in this process
(see Canvas fingerprinting).
So if one wants a base64 version of an image file, they have to request it again (most of the time it will come from cache) but this time as a Blob.
Then you can use a FileReader to read it either as an ArrayBuffer, or as a dataURL.
function toDataURL(url, callback){_x000D_
var xhr = new XMLHttpRequest();_x000D_
xhr.open('get', url);_x000D_
xhr.responseType = 'blob';_x000D_
xhr.onload = function(){_x000D_
var fr = new FileReader();_x000D_
_x000D_
fr.onload = function(){_x000D_
callback(this.result);_x000D_
};_x000D_
_x000D_
fr.readAsDataURL(xhr.response); // async call_x000D_
};_x000D_
_x000D_
xhr.send();_x000D_
}_x000D_
_x000D_
toDataURL(myImage.src, function(dataURL){_x000D_
result.src = dataURL;_x000D_
_x000D_
// now just to show that passing to a canvas doesn't hold the same results_x000D_
var canvas = document.createElement('canvas');_x000D_
canvas.width = myImage.naturalWidth;_x000D_
canvas.height = myImage.naturalHeight;_x000D_
canvas.getContext('2d').drawImage(myImage, 0,0);_x000D_
_x000D_
console.log(canvas.toDataURL() === dataURL); // false - not same data_x000D_
});
_x000D_
<img id="myImage" src="https://dl.dropboxusercontent.com/s/4e90e48s5vtmfbd/aaa.png" crossOrigin="anonymous">_x000D_
<img id="result">
_x000D_
If your image(s) are already loaded (or not), this "tool" may come in handy:
Object.defineProperty
(
HTMLImageElement.prototype,'toDataURL',
{enumerable:false,configurable:false,writable:false,value:function(m,q)
{
let c=document.createElement('canvas');
c.width=this.naturalWidth; c.height=this.naturalHeight;
c.getContext('2d').drawImage(this,0,0); return c.toDataURL(m,q);
}}
);
This has the advantage of using the "already loaded" image data, so no extra request in needed. Aditionally it lets the end-user (programmer like you) decide the CORS and/or mime-type
and quality
-OR- you can leave out these arguments/parameters as described in the MDN specification here.
If you have this JS loaded (prior to when it's needed), then converting to dataURL
is as simple as:
HTML
<img src="/yo.jpg" onload="console.log(this.toDataURL('image/jpeg'))">
JS
console.log(document.getElementById("someImgID").toDataURL());
If you are concerned about the "preciseness" of the bits then you can alter this tool to suit your needs as provided by @Kaiido's answer.
A more modern version of kaiido's answer using fetch would be:
function toObjectUrl(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
Edit: As pointed out in the comments this will return an object url which points to a file in your local system instead of an actual DataURL so depending on your use case this might not be what you need.
You can look at the following answer to use fetch and an actual dataURL: https://stackoverflow.com/a/50463054/599602
In HTML5 better use this:
{
//...
canvas.width = img.naturalWidth; //img.width;
canvas.height = img.naturalHeight; //img.height;
//...
}
Use onload
event to convert image after loading
function loaded(img) {_x000D_
let c = document.createElement('canvas')_x000D_
c.getContext('2d').drawImage(img, 0, 0)_x000D_
msg.innerText= c.toDataURL();_x000D_
}
_x000D_
pre { word-wrap: break-word; width: 500px; white-space: pre-wrap; }
_x000D_
<img onload="loaded(this)" src="https://cors-anywhere.herokuapp.com/http://lorempixel.com/200/140" crossorigin="anonymous"/>_x000D_
_x000D_
<pre id="msg"></pre>
_x000D_
Source: Stackoverflow.com