Reputation: 345
I'm using javascript in Tampermonkey (in Google Chrome) and I like to compare two images if they are identical / quite similar.
I thought I could do it by using a canvas element and compare the resulting strings, like that but no matter what images I choose, I always get that they are identical... : /
So the comparison doesn't seem to work and I have no idea why?
Edit 1: Added a timer to wait for the images to load /
/ ==UserScript==
// @name ImageCompare
// @namespace http://tampermonkey.net/
// @version 0.1
// @description try to take over the world!
// @author You
// @match *://*/*
// @match www*
// @grant none
// ==/UserScript==
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
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,/, "");
}
var x = new Image();
var y = new Image();
var url_x = "https://cdn0.tnwcdn.com/wp-content/blogs.dir/1/files/2010/03/google_logo.jpg";
var url_y = "https://nairobigarage.com/2017/wp-content/uploads/2015/02/6_logo_predesign.jpg";
x.src = 'chrome://favicon/' + url_x;
y.src = 'chrome://favicon/' + url_y;
var x_base64 = getBase64Image(x);
var y_base64 = getBase64Image(y);
sleep(5000).then(() => {
if (x_base64 === y_base64)
{
alert("identical");
}
else
{
alert("not identical");
}
});
Upvotes: 3
Views: 4277
Reputation: 42736
You need to wait for the images to load, you can use the onload
event to notify you when the image has loaded
var img = new Image();
img.onload = ()=>{
//do work
};
So:
function getBase64Image(img) {
var canvas = document.createElement("canvas");
canvas.width = img.width;
canvas.height = img.height;
var ctx = canvas.getContext("2d");
ctx.drawImage(img, 0, 0);
var dataURL = canvas.toDataURL("image/png");
return dataURL.replace(/^data:image\/(png|jpg);base64,/, "");
}
var x = new Image();
var y = new Image();
var url_x = "https://cdn0.tnwcdn.com/wp-content/blogs.dir/1/files/2010/03/google_logo.jpg";
var url_y = "https://nairobigarage.com/2017/wp-content/uploads/2015/02/6_logo_predesign.jpg";
x.src = 'chrome://favicon/' + url_x;
y.src = 'chrome://favicon/' + url_y;
//make the load events into promises
var xPromise = new Promise((resolve)=>{
x.onload = resolve;
});
var yPromise = new Promise((resolve)=>{
y.onload = resolve;
});
Promise.all([xPromise,yPromise]).then(()=>{
var x_base64 = getBase64Image(x);
var y_base64 = getBase64Image(y);
if(x_base64 == y_base64){
//match
} else {
//no match
}
});
Note though you are trying to load resources from chrome://
protocol, due to security restrictions you cannot actually get the data of cross origin resources. Either load resources from the same domain that your page is running, or use file inputs to get the image.
Upvotes: 5