【问题标题】:Compare two Images in JavaScript在 JavaScript 中比较两个图像
【发布时间】:2011-08-29 07:06:14
【问题描述】:

我正在尝试确定两个图像在 JavaScript 中是否相同(即使源 URL 不同)。

我的具体用例在 Chrome 扩展程序中(尽管这是一个 chrome 扩展程序并没有真正考虑到问题)。我可以通过将 img src 设置为: 'chrome://favicon/'+url 其中“url”是网站的实际 URL。但是,我现在想找到所有独特的网站图标。鉴于它们都有不同的内部数据库 URL,有没有一种简单的方法来比较 JavaScript 中的图像?

【问题讨论】:

  • 它可能确实会影响等式,因为您在扩展程序中拥有比浏览器中的一般 javascript 更多的设施和权限。

标签: javascript image compare


【解决方案1】:

如果其他人像我一样最终来到这里,因为他们试图比较 Node javascript 中的两个图像,我可以利用 NodeBuffergif 转换为 AWS S3 对象转换为 Base64 并对其进行测试。

这在 CypressJS 中用于测试发送到 S3 的图像,然后在测试中使用 s3.getObject() 返回 image

const imageToBase64 = Buffer.from(image.Body).toString('base64');

【讨论】:

    【解决方案2】:

    这可能是一个非常古老的线程,当我需要实现逐像素比较 2 个图像而不是相似性比较的相同目标时,我遇到了它。我找到了一个非常快速且易于使用的 PNG 图像逐像素比较 js 库的工具。这是 repo 提供的一个简单示例:

    const fs = require('fs');
    const PNG = require('pngjs').PNG;
    
    const pixelmatch = require('pixelmatch');
    
    const img1 = PNG.sync.read(fs.readFileSync('img1.png'));
    const img2 = PNG.sync.read(fs.readFileSync('img2.png'));
    
    const {width, height} = img1;
    const diff = new PNG({width, height});
    
    pixelmatch(img1.data, img2.data, diff.data, width, height, {threshold: 0.1});
    
    fs.writeFileSync('diff.png', PNG.sync.write(diff));
    

    它甚至会为您生成差异图像。请注意,这不是感知比较。还有其他用于此目的的工具。
    这是 GitHub 上像素匹配的链接: pixelmatch on github

    【讨论】:

    • 嗯...这个工具似乎没有提供一种方法来判断两个图像在 JavaScript 中是否相同。尽我所能,直到它产生只能由人类确定的图像输出。它真正需要做的就是返回truefalse
    【解决方案3】:

    我想你可能对这个名为 resemble.js 的 JavaScript 库感兴趣:

    使用 HTML5 画布和 JavaScript 分析和比较图像。

    Resemble.js 可用于您在浏览器中可能有的任何图像分析和比较要求。但是,它是为https://github.com/Huddle/PhantomCSS 支持的视觉回归库 PhantomCSS 设计和构建的。 PhantomCSS 需要能够忽略抗锯齿,因为这会导致来自不同机器的屏幕截图之间存在差异。

    Resemble.js 使用 HTML5 File API 解析图像数据,并使用画布呈现图像差异。

    【讨论】:

      【解决方案4】:

      我们刚刚发布了一个轻量级库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
          }
        })
      

      如您所见,如果您的域在颜色或像素差异方面需要一些余地,则伦勃朗还允许您引入阈值。由于它可以在浏览器和服务器(节点)上运行,因此可以轻松集成到您的测试套件中。

      【讨论】:

      • 我无法让它工作。我只是想测试一下,这张图片是否看起来完全一样。你可以在这里查看我的测试:cdn.axiell.com/~dev/gota/image-test/html-template.html。进行测试的代码非常简单明了。但即使这些图像相同,结果也是它们不同。
      • 两张图都是灰度图会不会更容易些?
      • 比较方法出现“ReferenceError: window is not defined”
      【解决方案5】:

      也许这个工具会有所帮助: https://github.com/HumbleSoftware/js-imagediff/

      【讨论】:

        【解决方案6】:

        不,没有特别简单的方法可以做到这一点。 JavaScript 不是为处理低级操作而设计的,例如直接处理二进制数据以进行图像处理。

        您可以use a <canvas> element to base64 encode each image,然后比较生成的base64 字符串,但这只会告诉您图像是否相同。

        要使用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
        }
        

        【讨论】:

        • 或者将它们写入 2 个画布并检查每个画布的像素,然后将它们与某种时髦的算法进行比较。但老实说,这听起来很难。
        • 我认为你成功了——“告诉你图片是否相同”——这不是他们想要的;)
        • 这个答案+1。类似于nude.js 的东西在客户端/JavaScript davidwalsh.name/nudejs 上尽可能接近
        猜你喜欢
        • 1970-01-01
        • 2015-05-27
        • 2018-12-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-04-26
        • 2012-04-04
        相关资源
        最近更新 更多