在 JavaScript 中比较两个图像
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6066111/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Compare two Images in JavaScript
提问by JMH
I am trying to determine if two images are the same in javascript (even if the src urls are different).
我试图确定两个图像在 javascript 中是否相同(即使 src url 不同)。
My specific use case is within a chrome extension (though this being a chrome extension doesn't really factor into the question). I can get the imgage of a favicon png stored within chrome's internal database by setting the img src to:
'chrome://favicon/'+url
where the url is the actual url of the website. However, I now want to find all the unique favicons. Given that they all will have a different URL to the internal database, is there an easy way to compare images in javascript?
我的具体用例在 chrome 扩展中(尽管这是一个 chrome 扩展并没有真正影响问题)。我可以通过将 img src 设置为:'chrome://favicon/'+url
其中 url 是网站的实际 url来获取存储在 chrome 内部数据库中的 favicon png 的图像
。但是,我现在想找到所有独特的图标。鉴于它们都有不同的内部数据库 URL,是否有一种简单的方法来比较 javascript 中的图像?
Thanks
谢谢
回答by Matt Ball
No, there is no especially easyway to do this. JavaScript was not made for handling low-level operations such as working directly with binary data for, say, image processing.
不,没有特别简单的方法可以做到这一点。JavaScript 不是为处理低级操作而设计的,例如直接使用二进制数据进行图像处理。
You could use a <canvas>
element to base64 encode each image, and then compare the resulting base64strings, but this will only tell you whether or not the images are identical.
您可以使用<canvas>
元素对每个图像进行 base64 编码,然后比较生成的base64字符串,但这只会告诉您图像是否相同。
To use the getBase64Image
function (defined in the answer I linked) to compare two images:
要使用该getBase64Image
函数(在我链接的答案中定义)来比较两个图像:
var a = new Image(),
b = new Image();
a.src = 'chrome://favicon/' + url_a;
b.src = 'chrome://favicon/' + url_b;
// might need to wait until a and b have actually loaded, ignoring this for now
var a_base64 = getBase64Image(a),
b_base64 = getBase64Image(b);
if (a_base64 === b_base64)
{
// they are identical
}
else
{
// you can probably guess what this means
}
回答by Igor Milla
I think you may be interested in this JavaScript library called resemble.jswhich:
我想你可能对这个名为Similar.js 的JavaScript 库感兴趣,它:
Analyses and compares images with HTML5 canvas and JavaScript.
Resemble.jscan be used for any image analysis and comparison requirement you might have in the browser. However, it has been designed and built for use by the https://github.com/Huddle/PhantomCSSpowered visual regression library PhantomCSS. PhantomCSS needs to be able to ignore antialiasing as this would cause differences between screenshots derived from different machines.
Resemble.js uses the HTML5 File APIto parse image data, and canvas for rendering image diffs.
使用 HTML5 画布和 JavaScript 分析和比较图像。
Resemble.js可用于您在浏览器中可能有的任何图像分析和比较需求。但是,它是为https://github.com/Huddle/PhantomCSS支持的视觉回归库 PhantomCSS设计和构建的。PhantomCSS 需要能够忽略抗锯齿,因为这会导致来自不同机器的屏幕截图之间存在差异。
Resemble.js 使用HTML5 文件 API来解析图像数据,并使用画布来呈现图像差异。
回答by Jan Bussieck
We just released a lightweight library RembrandtJS, that does exactly that and it works both in the browser using HTML5 Canvas2D API as well as on the server via the drop-in Node.JS replacement node-canvas. It accepts both blobs and urls as image sources so you could simply do this:
我们刚刚发布了一个轻量级库RembrandtJS,它就是这样做的,它既可以在使用 HTML5 Canvas2D API 的浏览器中运行,也可以通过插入式 Node.JS 替换节点画布在服务器上运行。它接受 blob 和 url 作为图像源,因此您可以简单地执行以下操作:
const rembrandt = new Rembrandt({
// `imageA` and `imageB` can be either Strings (file path on node.js,
// public url on Browsers) or Buffers
imageA: 'chrome://favicon/' + url_a,
imageB: 'chrome://favicon/' + url_b,
thresholdType: Rembrandt.THRESHOLD_PERCENT,
// The maximum threshold (0...1 for THRESHOLD_PERCENT, pixel count for THRESHOLD_PIXELS
maxThreshold: 0,
// Maximum color delta (0...255):
maxDelta: 0,
// Maximum surrounding pixel offset
maxOffset: 0,
})
// Run the comparison
rembrandt.compare()
.then(function (result) {
if(result.passed){
// do what you want
}
})
As you can see Rembrandt also allows you to introduce threshold values, if you domain requires some leeway with respect to color or pixel difference. Since it works in both the browser and on the server (node), it makes it easy to integrate into your test suite.
如您所见,伦勃朗还允许您引入阈值,如果您的领域在颜色或像素差异方面需要一些余地。由于它可以在浏览器和服务器(节点)上运行,因此可以轻松集成到您的测试套件中。
回答by vitopn
Maybe this tool will help: https://github.com/HumbleSoftware/js-imagediff/
也许这个工具会有所帮助:https: //github.com/HumbleSoftware/js-imagediff/