教你如何成为图片找茬高手

事情是这样的,前几天闲来无事,手机上下载了个图片找茬游戏,本以为是小孩子玩玩的很简单,没想到开头几关就把我难住了,有些细节真是藏的很深呀,不仔细看真的找不到。于是乎我想,肉眼很难辨别的东西是不是可以通过代码帮我快速找到?前端有 canvas 可以用来处理图像,查了下 API 也可以读取像素点,感觉可行,说干就干!

canvas 读取像素点

我们知道,canvas 是可以拷贝图像的,通过 ctx.drawImage,我们可以方便的将图片绘制在 canvas 里面,下面是例子

tsx 复制代码
  const canvas = document.createElement("canvas");
  const ctx = canvas.getContext("2d");
  const image = new Image();
  image.src = 'xxx';
  image.onload = ()=> {
   canvas.width = image.width;
   canvas.height = image.height;
   ctx.drawImage(image, 0, 0);
  }

但应该没多少童鞋知道,canvas 其实也可以读取像素点,通过 ctx.getImageData 我们可以方便的读取当前绘制图片的像素点数组。

tsx 复制代码
  const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height).data;

然后我们会得到如下数组

tsx 复制代码
  // [255,254,255,255,...]

这里每4个值一组就代表了一个像素点,聪明的童鞋已经看出来了,没错,这4个值分别对应了 RGBA,如下图所示 我们可以通过对比每一个像素点,来实现图片的差异化对比。

绘制差异化像素点

既然能读取,我们能不能修改里面的像素点呢?答案是可以的,通过ctx.putImageData,我们可以方便的对现有图像的像素进行随意改造,比较常用的就是 滤镜,通过不同的滤镜算法,我们可以在网页上实现类似美图秀秀的功能,当然在我们这个需求里,也可以用来标记差异化的像素点。具体流程如下:

  1. 绘制需要对比的两张图片到 canvas
  2. 获取原图的像素点数组作为对照
  3. 遍历对比图的像素点,将和原图不同的部分用蓝色重新赋值
  4. 通过ctx.putImageData,重新生成新的图像信息
  5. 最后通过 canvastoDataURL api 生成 base64 图像

简单写了个 demo,效果类似这样

我们可以很快发现,diff 图 里蓝色明显的地方即为差异点

源代码我放在 github 上了,有兴趣的童鞋自取~ 👉 image-diff-demo

抛砖引玉

经过这个小 demo 的实战,深入理解了 ctx.getImageDatactx.putImageData 的用法,虽然原理差不多是这样子,但是还是有很多可以优化的地方,比如对比原图发现,很多没改动的地方也染上了一些蓝色,这个原因是因为两张图的相同部分的像素点也是不一致的,受限于图片压缩问题,很多颜色也是会有些许出入,虽然肉眼看不出来,但实际上从像素角度出发是不一样的,大家也可以想想怎么优化 diff 算法 可以让误差尽量减小😁

总结

image-diff 也不是新东西了,市面上也有不少成熟的产品了,开源社区耳熟能详的就是大名鼎鼎的 argos-ci,还有开源产品,比如 Resemble.js,都是比较好的 image-diff 库,大家可以按需使用,当然也可以自研,原理其实并不难。希望本篇文章对大家有帮助~

相关推荐
vivo互联网技术35 分钟前
下一代图片格式 AVIF 在 vivo 社区的落地实践
前端·性能优化·图片压缩·avif
咸鱼翻身更入味37 分钟前
Vue创建一个简单的Agent聊天
前端
布局呆星44 分钟前
Vue Router 核心知识点梳理
前端·javascript·vue.js
得物技术1 小时前
基于 Harness + SDD + 多仓管理模式的 AI 全栈开发实践|得物技术
前端·人工智能·后端
不会写DN1 小时前
如何通过 Python 实现招聘平台自动投递
开发语言·前端·python
miaowmiaow1 小时前
一行命令把 PSD 还原成 HTML / React / Vue:psd2code 实战干货
前端·ai编程
张元清1 小时前
React 中的语音与摄像头输入:语音识别、媒体设备与权限
前端·javascript·面试
用户841794814561 小时前
vxe-table 实现撤销与重做:单元格编辑后支持 Ctrl+Z 回退
前端
石小石Orz1 小时前
OpenAI官方:harness-engineering(工程技术:在智能体优先的世界中利用 Codex)
前端·后端