专业编程教程与实战项目分享平台

网站首页 > 技术文章 正文

前端自动化:全网最火的5大开源图片相似性对比库!

ins518 2025-05-26 16:29:47 技术文章 13 ℃ 0 评论

大家好,很高兴又见面了,我是"高级前端进阶",由我带着大家一起关注前端前沿、深入前端底层技术,大家一起进步,也欢迎大家关注、点赞、收藏、转发!

最近在做一些自动化测试相关的安全发布卡口,即投前安全、稳定性保障机制建设。很容易想到的一个方向就是基于图片对比。

因此本文将重点列举几个非常优秀的图片对比方案。当然,这种逐像素对比的技术是否适合你的项目需要依照具体情况而定。话不多说,直接进入正题!

1.pixelmatch

什么是 pixelmatch

pixelmatch是最小、最简单、最快的 JavaScript 像素级图像比较库,最初是为了在测试中比较屏幕截图而创建的。具有准确的抗锯齿像素检测和感知色差指标。

当然,pixelmatch 受到了 Resemble.js 和 Blink-diff 的启发。 与这些库不同的是,pixelmatch 大约有 150 行代码,没有依赖关系,并且适用于图像数据的原始类型数组,因此它非常快而且可以在任何环境(Node.js 或浏览器)中使用。

如何使用 pixelmatch

在Node.js环境中需要先安装,安装后通过如下方法即可快速使用:

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));

浏览器环境中需要先引入相关的CDN资源,然后直接调用相关方法即可:

const img1 = img1Context.getImageData(0, 0, width, height);
const img2 = img2Context.getImageData(0, 0, width, height);
const diff = diffContext.createImageData(width, height);

pixelmatch(img1.data, img2.data, diff.data, width, height, {threshold: 0.1});
// 方法签名: pixelmatch(img1, img2, output, width, height[, options])
diffContext.putImageData(diff, 0, 0);

目前pixelmatch在Github上有5.3k的star、387k的项目使用它,NPM周平均下载量达到了2062k,妥妥的前端明星项目。

2.Resemble.js

什么是Resemble.js

Resemble.js 是 James Cryer 开发的一个 js 小型 (~11kb) JavaScript 库,可帮助开发者在浏览器中分析和比较图像。 唯一的依赖是 HTML5 File API(用于解析数据)和 HTML5 Canvas(用于渲染差异)。

需要注意的是,Resemble.js 使用 node-canvas 来支持 Node.js 环境。 这是一个预构建的依赖项,在某些环境中可能会失败。 如果开发者仅将 Resemble.js 用于浏览器内分析,则可以使用 npm install --no-optional 跳过 node-canvas 依赖项。

如果开发者确实需要 Node.js 支持并且 Canvas 依赖项失败,可以尝试使用以前版本的 Resemble.js,或 npm install --build-from-source。

使用Resemble.js

下面的示例是对图片的基础分析:

var api = resemble(fileData).onComplete(function (data) {
    console.log(data);
 /*
	{
	  red: 255,
	  green: 255,
	  blue: 255,
	  brightness: 255
	}
	*/
});

下面的示例用于对比两个图片:

var diff = resemble(file)
    .compareTo(file2)
    .ignoreColors()
    .onComplete(function (data) {
        console.log(data);
    });

如果是Node.js环境中,API 与 resemble.compare 相同,但是是基于 promise的:

const compareImages = require("resemblejs/compareImages");
const fs = require("mz/fs");
async function getDiff() {
    const options = {
        output: {
            errorColor: {
                red: 255,
                green: 0,
                blue: 255
            },
            errorType: "movement",
            transparency: 0.3,
            largeImageThreshold: 1200,
            useCrossOrigin: false,
            outputDiff: true
        },
        scaleToSameSize: true,
        ignore: "antialiasing"
    };
    const data = await compareImages(await fs.readFile("./your-image-path/People.jpg"), await fs.readFile("./your-image-path/People2.jpg"), options);
    await fs.writeFile("./output.png", data.getBuffer());
}
getDiff();

目前Resemble.js在Github上有4.3k的star、1.7k的项目使用它,NPM周平均下载量31k,是一个值得关注的前端项目。

3.blink-diff

blink-diff是一个轻量级的图像比较工具,可以使用下面命令快速安装它:

npm install blink-diff

blink-diff的使用也是非常简单,而且支持的参数也是非常多。比如下面的示例:

var firstImage = PNGImage.readImage('path/to/first/image', function (err) {
  if (err) {
    throw err;
  }

  var diff = new BlinkDiff({
      imageA: srcImage, 
      // 使用已加载的图像作为第一张图像
      imageBPath: 'path/to/second/image',
      // 使用文件路径选择图像
      delta: 50, 
      // 让比较更宽容
      outputMaskRed: 0,
      outputMaskBlue: 255, 
       // 使用蓝色突出差异
      hideShift: true, 
      // 隐藏抗锯齿差异 - 仍会确定但不显示
      imageOutputPath: 'path/to/output/image'
  });

  diff.run(function (error, result) {
    if (error) {
      throw error;
    } else {
      console.log(diff.hasPassed(result.code) ? 'Passed' : 'Failed');
      console.log('Found ' + result.differences + ' differences.');
    }
  });
});

目前 blink-diff 在Github上有1.2k的star、1.4k的项目使用它,NPM周平均下载量62k,是一个值得关注的前端项目。

4.looks-same

什么是 looks-same

looks-same 是用于比较图像的 Node.js 库,同时考虑到人类的颜色感知。它是专门为 hermione 实用程序的视觉回归测试的需要而创建的,但可以用于其他目的。

looks-same 目前支持 JPEG、PNG、WebP、GIF、AVIF、TIFF 和 SVG 图像。

注意:如果要比较 jpeg 文件,如果它们不是无损 jpeg 文件,由于 jpeg 结构,可能会遇到随机差异。

使用 looks-same

使用look-same也是非常简单,比如下面的代码示例:

const looksSame = require('looks-same');
// equal will be true, if images looks the same
const {equal} = await looksSame('image1.png', 'image2.png');

参数可以是文件路径或带有压缩图像的缓冲区。 默认情况下,它只会检测明显的差异。如果想检测任何差异,请使用strict选项:

const {equal} = await looksSame('image1.png', 'image2.png', {strict: true});

文本输入元素中的文本插入符对于视觉回归任务来说是一种痛苦,因为它总是闪烁。 默认情况下将忽略这些差异。 开发者可以使用带有 false 值的 ignoreCaret 选项来禁用忽略此类差异。 这样,文本插入符号将被标记为差异。

const {equal} = await looksSame('image1.png', 'image2.png', {ignoreCaret: true});
// strict 和 ignoreCaret 都可以相互独立设置。

由于抗锯齿,有些图像在比较时存在差异。 默认情况下将忽略这些差异,开发者可以使用带有 false 值的 ignoreAntialiasing 选项来禁止忽略此类差异。 这样,抗锯齿像素将被标记为差异。

const {equal} = await looksSame('image1.png', 'image2.png', {ignoreAntialiasing: true});

关于look-same的更多用法这里不再继续展开,可以参考文末的资料继续研究。

目前 look-same 在Github上有0.51k的star、2.1k的项目使用它,NPM周平均下载量54k,是一个值得关注的前端项目。

5.其他方案

根据npm-trend的数据,还找到了image-comparer 、image-diff 、image-diffr等其他对比方案,现在对这几种方案进行简单说明:

  • image-diff:已停止维护,官方建议使用 looks-same 和 pixelmatch 替代方案,目前Github上有2.4k的star。
  • image-diffr:用于比较两个图像之间相似性的简单工具。 适用于 PNG 和 JPG,无论是从命令行还是作为可导入的模块。 根据阈值以图像之间差异的加权百分比进行响应,和/或生成突出显示两个输入之间差异的新图像。但是这个方案目前Github的采纳量非常有限,不建议使用

6.本文总结

本文重点列举了几个非常优秀的图片对比方案,如:pixelmatch 、Resemble.js 、blink-diff 、looks-same 、image-diff等等,同时对每一个方案的简单用法进行了介绍。当然,这种逐像素对比的技术是否适合真实项目需要依照具体情况而定,或者做一些其他方案补充。

因为篇幅有限,文章并没有过多展开,如果有兴趣,可以在我的主页继续阅读,同时文末的参考资料提供了大量优秀文档以供学习。最后,欢迎大家点赞、评论、转发、收藏!


参考资料

https://github.com/mapbox/pixelmatch

https://github.com/rsmbl/Resemble.js

https://changelog.com/posts/analyze-and-compare-images-with-resemble-js

http://yahoo.github.io/blink-diff/

https://github.com/yahoo/blink-diff

https://github.com/gemini-testing/looks-same

https://github.com/jhartman86/image-diffr

https://github.com/uber-archive/image-diff

https://www.jqueryscript.net/blog/best-image-comparison.html

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表