整理项目时看到两年前对图片的一个处理实验,想要简单对图片颜色进行一个反转的尝试,结果最后总是什么都显示不出来,当时就放弃了,于是花十五分钟检查了下之前的问题,记录下再删除~
页面很简单,就包含了一个canvas
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>测试</title>
</head>
<body>
<canvas id="myCanvas"></canvas>
</body>
<script src="./index.js"></script>
</html>
js代码就是加载了路径下的一张图,加载完成后写到canvas里。
1.先获取到canvas容器,根据图片宽高定义好容器大小
let canvasCon = document.getElementById("myCanvas")
if (!canvasCon) return
canvasCon.width = imgDom.width
canvasCon.height = imgDom.height
2.拿到容器画笔,通过getImageData获取图片具体像素
let ctx = canvasCon.getContext("2d")
let imgData = ctx.getImageData(0,0,canvas.width, canvas.height)
let data = imgData.data
3.对像素进行任意操作来改变图像内容,比如一个简单的反转
for(let i = 0;i < data.length; i+=4){
data[i+0]=255-data[i+0];
data[i+1]=255-data[i+1];
data[i+2]=255-data[i+2];
data[i+3]=255;
}
这边需要注意的是,data是把[width, height, chanel]平铺开了的一个数组,所以实际上每4位代表1个像素,分别是[r,g,b,a] 其中第4位a代表透明度
像我之前的问题有两个,一个是不清楚展开的结构,对data里每一个数字都进行里255-data[i]的操作,如果是正常的图片,那么阿尔法通道也会从255变成了0,(0代表透明),自然改变后图片就消失了
4.把更改后的数据重新放回canvas容器渲染
ctx.putImageData(imgData,0,0)
更改成3的像素处理后图片仍然还是什么都没有~检查发现我处理的是一张png图,每个像素点rgb值都是(0,0,0),通过a通道控制颜色,反转完rgb变成了(255,255,255),就变成了白色消失了……于是换了一张正常的jpg图。处理前后效果如下:

image.png
对png图片做反转的话也比较简单,无需对rgb取反,直接对阿尔法通道取反即可。
for(let i = 0;i < data.length; i+=4){
data[i+3] = 255 - data[i+3]
}

image.png