请马上登录,朋友们都在花潮里等着你哦:)
您需要 登录 才可以下载或查看,没有账号?立即注册
x
本帖最后由 马黑黑 于 2024-4-21 08:33 编辑
canvas画布是HTML的一个特殊的图像处理标签,它以像素为操作单位,每一个像素的颜色都可以标记为 rgba 四个颜色单元,r 代表红色、g 代表绿色、b 代表蓝色、a 代表Alpha通道,四个颜色值的取值范围都是 0~255,其中 a 为 0 表示完全透明、255表示完全不透明。
canvas通过JS操纵画笔,假设画布标识为 ctx,现在我们想拿到画布上每一个像素的数据,可以使用 ctx.getImageData() 方法达成:
var imageData = ctx.getImageData(x, y, width, height);
getImageData需要四个参数,x、y 为要获取数据的画布起始点xy坐标,width、height为获取数据的宽高尺寸,它将返回一个对象,里面包含了丰富的信息,其中,data 将是我们感兴趣的:
var data = imageData.data;
等号左边的 data 是我们声明的变量,等号右边的 data 是前面获取到的对象的 imageData 的数组数据,它记录了所有像素的 rgba 数值,我们只需对其进行逐一操作便可更改图像的颜色构成。需要注意的是,data 数组元素由 r、g、b、a 四个单元构成,换句话说,每一个像素从头到尾对应 data 数组的四个数据单元,为此,我们在遍历 data 数组时,步进步幅应为 4,这样恰好每一次循环处理一个像素。一个图像的像素量都是庞大的,以下是一张大白兔的图片,其尺寸为 658*528=347424(像素),在画布中的 data 数据则达 347424*4=1389696 之多:

我们就拿这只可爱的大白兔开刀——哦不,给它染毛,让它变成一只大红兔是不是更可爱?先上效果:
我去,这是怎么做到的?看一下代码吧:
<canvas id="canv"></canvas>
<script>
var ctx = canv.getContext("2d");
var img = new Image();
img.crossOrigin = 'anonymous'; //跨域
img.src = 'https://638183.freep.cn/638183/t24/webp/rabbit.webp';
img.onload = function() {
var w = canv.width = img.width, h = canv.height = img.height;
ctx.drawImage(img, 0, 0);
var imageData = ctx.getImageData(0, 0, w, h);
var data = imageData.data;
console.log(data.length);
for(var i = 0; i < data.length; i += 4) {
data[i + 1] = 0; //拿掉绿色
data[i + 2] = 0; //拿掉蓝色
};
ctx.putImageData(imageData, 0, 0); //将更改后的数据写入画布
};
</script>
道理很简单:通过 getImageData 拿到画笔绘制的初始图像数据集合,然后将每一个像素里的颜色构成中的蓝色和绿色设置为 0 ,再用 putImageData() 方法将修改过的图像数据写回画布替换了原先的图像。这里的 putImageData() 方法语法结构很简单:数据集合,开始绘制的位置xy坐标。
可以将上述完整代码存为本地 .html 文档,或将代码拿到 pencil code,通过修改相关数据以查看更多的效果。提示:红色的读写,data[ i ],Alpha 的读写,data[i + 3],这是一一对应的。
|