我试图确定 JavaScript 中的两个图像是否相同(即使源 URL 不同)。
我的具体用例是在 Chrome 扩展程序中(尽管这是一个 Chrome 扩展程序并没有真正考虑到问题)。我可以通过将 img src 设置为:来获取存储在 Chrome 内部数据库中的 favicon png 图像:
'chrome://favicon/'+url
其中“url”是网站的实际 URL。但是,我现在想找到所有独特的图标。鉴于它们都有不同的内部数据库 URL,是否有一种简单的方法可以在 JavaScript 中比较图像?
I am trying to determine if two images are the same in JavaScript (even if the source URLs are different).
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 image of a favicon png stored within Chrome's internal database by setting the img src to:
'chrome://favicon/'+url
where '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?
发布评论
评论(8)
不,没有特别简单的方法来做到这一点。 JavaScript 并不是为处理低级操作而设计的,例如直接处理二进制数据以进行图像处理。
您可以使用
元素对每个图像进行base64编码< /a>,然后比较生成的 base64 字符串,但这只会告诉您是否图像是相同的。
要使用 getBase64Image 函数(在我链接的答案中定义)来比较两个图像:
No, there is no especially easy way to do this. JavaScript was not made for handling low-level operations such as working directly with binary data for, say, image processing.
You could use a
<canvas>
element to base64 encode each image, and then compare the resulting base64 strings, but this will only tell you whether or not the images are identical.To use the
getBase64Image
function (defined in the answer I linked) to compare two images:我想您可能对这个名为 resemble.js 的 JavaScript 库感兴趣,其中:
I think you may be interested in this JavaScript library called resemble.js which:
我们刚刚发布了一个轻量级库 RembrandtJS,它正是这样做的,并且它可以使用 HTML5 Canvas2D API 在浏览器中运行以及在服务器上通过嵌入式 Node.JS 替换节点画布。
它接受 blob 和 url 作为图像源,因此您可以简单地执行此操作:
如您所见,如果您的域需要在颜色或像素差异方面有一定的余地,Rembrandt 还允许您引入阈值。由于它可以在浏览器和服务器(节点)上运行,因此可以轻松集成到您的测试套件中。
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:
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.
也许这个工具会有所帮助:
https://github.com/HumbleSoftware/js-imagediff/
Maybe this tool will help:
https://github.com/HumbleSoftware/js-imagediff/
这可能是一个非常古老的线程,当我需要实现逐像素比较 2 个图像而不是相似性比较的相同目标时,我遇到了它。我发现了一个非常快速且易于使用的 PNG 图像逐像素比较工具 js 库。这是存储库提供的一个简单示例:
它甚至为您生成一个差异图像。请注意,这不是感性比较。还有其他用于此目的的工具。
以下是 GitHub 上像素匹配的链接:
github 上的像素匹配
This is probably a very old thread and I ran into it when I needed to achieve the same goal of comparing 2 images pixel by pixel instead of similarity comparison. I found a very fast and easy to use tool for PNG image pixel by pixel comparison js library. Here is a simple example provided by the repo:
It even generates a diff image for you. Please note this is NOT perceptual comparison. There are other tools for such purpose.
Here is the link on GitHub for pixelmatch:
pixelmatch on github
这是在浏览器中使用 Pixelmatch 且无需捆绑的完整、可运行的示例。
Here's a complete, runnable example of using pixelmatch in the browser without bundling.
基于浏览器的文件比较
此答案解决了关于一个已关闭的重复问题 q/73314528/5217142">如何在浏览器中比较两个图像,例如打开或拖放到页面上,不使用画布或base64。
高级答案是获取每个文件的数组缓冲区,使用它们创建数据视图或实际类型化数组并逐字节检查它们。
这个简单的示例说明了原理,做出了一些可以通过使用
Blob.arrayBuffer
为文件数据缓冲区创建 Promise,以及new Uint8Array
构造类型化数组,而不是创建 DataView 对象。为了提高效率,代码片段的生产版本可以使用
file
对象的size
属性来检查文件之前是否具有相同的非零长度读取它们以便逐字节比较它们的内容。Browser based file comparison
This answer addresses a closed as duplicate question about how to compare two images in a browser, say opened or dropped onto the page, without using canvas or base64.
The high level answer is to get array buffers for each of the files, use them to create a data view or actual typed array and check them byte by byte.
This bare bones example illustrates the principles, making some choices that could have been done differently by using
Blob.arrayBuffer
to create promises for buffers of file data, andnew Uint8Array
to construct a typed array as opposed to creating a DataView object.For efficiency, a production version of the snippet could use
file
objects'size
attributes to check the files have the same, non-zero length before reading them in order to compare their contents byte by byte.如果其他人像我一样最终来到这里,因为他们试图比较
Node
javascript
中的两个图像,我就能够利用Node
的Buffer
将gif
作为 AWS S3 对象转换为 Base64 并对其进行测试。在 CypressJS 中使用它来测试发送到 S3 的图像,然后在测试中使用 s3.getObject() 返回图像
const imageToBase64 = Buffer .from(image.Body).toString('base64');
If someone else ended up here like I did because they were trying to compare two images in
Node
javascript
, I was able to utilizeNode
'sBuffer
to convert agif
as an AWS S3 Object into a Base64 and test against it.This was used within CypressJS in order to test an image sent to S3 and then in the test using
s3.getObject()
to return theimage
const imageToBase64 = Buffer.from(image.Body).toString('base64');