canvas的ctx.getImageData和ctx.putImageData扫盲

前言

最近自己想做一个UI自动化测试工具,因为自己的页面第一页面少,第二适配多,根据这个场景,那么使用两张图片对比的测试就非常适合我这个场景,但是自己一直对canvas的不是太了解,自学过很多次,但是因为用的不多所以经常忘记,那么这次我们不学全部的,用到哪个api,就学哪个api

初始化绘制图片drawImage

const image1 = './img/1.jpeg';
const canvas = document.querySelector('#canvas');
// 如果想使用canvas的api,那么必须获取context对象,相当于一个接口
const ctx = canvas.getContext("2d");
// 等价于document.createElement("img").
const imageObj = new Image();
// 图片加载好以后开始进行操作
imageObj.onload = function(){
  ctx.drawImage(imageObj, 0, 0);
}
imageObj.src = image1;

canvas的ctx.getImageData和ctx.putImageData扫盲

咱们的美女图立马显示在电脑上

有人可能感叹了,怎么绘制一个图片这么麻烦,又要new Image(),又要src,又要onload的,这怎么记得住呢?

首先说一下为什么要new Image(), 因为drawImage的第一个参数必须是以下几种

canvas的ctx.getImageData和ctx.putImageData扫盲

所以这个没有办法

getImageData

getImageData是干什么的呢?
从字面上理解就是获取指定宽高的ImageData信息的,那么什么是imageData呢?

我们先来看一下imageData都返回哪些信息

canvas的ctx.getImageData和ctx.putImageData扫盲

  • width:图像区域的宽度。
  • height:图像区域的高度。
  • data:一个 Uint8ClampedArray 类型的数组,包含了每个像素的颜色信息。该数组按照从左到右、从上到下的顺序存储每个像素的 RGBA(红、绿、蓝、透明度)值。

这个data包含了每个像素的颜色信息,像不像颜色选择器的返回值呢,因为每个像素其实就是由这几个值构成的

canvas的ctx.getImageData和ctx.putImageData扫盲

显示器上的1像素是什么样子的呢

canvas的ctx.getImageData和ctx.putImageData扫盲

这不就是我们常写的rgb(255,255,255), 如果都不发光那么就是黑色rgb(0,0,0)

putImageData

putImageData是干什么用的呢?

从字面理解就是把imageData重新渲染到canvas上。也就是我们在通过getImageData获取到imageData以后,然后进行处理,再通过putImageData绘制到canvas上,接下来我们就以一个取反色的例子来演示一下效果

const dealImageData = (imageData) => {
  let data = imageData.data;
  for(let i=0;i<data.length;i+=4){
    // R 红色通道去反色
    data[i] = data[i]^255;
    // G 绿色通道去反色
    data[i+1] = data[i+1]^255;
    // B 绿色通道去反色
    data[i+2] = data[i+2]^255;
    // A 透明通道一般不取反色,因为你的图片有可能都是255,也就是不透明的,你取了反色,就成了全透明,什么都看不到了
    // data[i+3] = data[i+3]^255;
  }
  return imageData;
}

const image1 = './img/1.jpeg';
const canvas = document.querySelector('#canvas');
// 如果想使用canvas的api,那么必须获取context对象,相当于一个接口
const ctx = canvas.getContext("2d");
// 等价于document.createElement("img").
const imageObj = new Image();
// 图片加载好以后开始进行操作
imageObj.onload = function(){
  ctx.drawImage(imageObj, 0, 0);
  const imageData = ctx.getImageData(0, 0, imageObj.width, imageObj.height);
  const newImageData = dealImageData(imageData);
  ctx.clearRect(0, 0, imageObj.width, imageObj.height);
  ctx.putImageData(newImageData, 0, 0);
}
imageObj.src = image1;

上面的代码一定要注意,不是什么都可以取反色的,比如透明度就最好不要取反色,因为你的图片有可能都是255,也就是不透明的,你取了反色,就成了全透明,什么都看不到了

canvas的ctx.getImageData和ctx.putImageData扫盲

现在再看一下我们图片的效果,哦,好诡异,所以技术不能乱用哦,小心吓到自己

参考

原文链接:https://juejin.cn/post/7247167103873286181 作者:为了摸鱼而战

(0)
上一篇 2023年6月23日 上午11:02
下一篇 2023年6月23日 上午11:15

相关推荐

发表回复

登录后才能评论