getimagedata是html5 canvas实现像素级灰度滤镜的核心接口:先获取rgba像素数据,再按加权公式gray=0.299×r+0.587×g+0.114×b计算灰度值并赋给rgb分量,最后用putimagedata写回画布。

在HTML5 Canvas中,getImageData 是实现像素级图像处理的核心接口,去色(灰度)滤镜正是其典型应用:通过读取每个像素的RGBA值,按加权平均公式转为灰度,再用 putImageData 写回画布。
获取图像数据并遍历像素
先确保图像已加载完成,再将其绘制到Canvas上,调用 ctx.getImageData(0, 0, width, height) 获取包含所有像素的 ImageData 对象。该对象的 .data 属性是一个一维 Uint8ClampedArray,每4个连续元素代表一个像素的 R、G、B、A 值(范围 0–255)。
遍历时注意步长为4(跳过alpha通道参与计算,但需保留):
- 循环索引
i从0到data.length,每次递增4 -
data[i]是红色分量,data[i+1]是绿色,data[i+2]是蓝色,data[i+3]是透明度
应用灰度转换算法
标准去色不是简单取平均(R+G+B)/3,而是采用人眼对颜色敏感度不同的加权公式:
gray = 0.299 × R + 0.587 × G + 0.114 × B
这个系数来自YUV色彩空间的亮度(Y)分量,能更好保留视觉明暗层次。计算后将结果同时赋给 R、G、B 三个位置:
data[i] = data[i+1] = data[i+2] = gray- 保持
data[i+3](alpha)不变,避免影响透明度 - 结果需用
Math.round()或位运算(如|0)转为整数,因Uint8ClampedArray只接受 0–255 整数
写回画布并优化性能
处理完所有像素后,调用 ctx.putImageData(imageData, 0, 0) 将修改后的数据渲染到画布。注意以下细节:
- 必须使用与
getImageData相同尺寸的 canvas,否则会报错或裁剪 - 若图像较大(如 >1000×1000),遍历可能造成卡顿;可考虑用
requestIdleCallback分块处理,或启用 Web Worker 离主线程计算 - 为兼容性,确保 canvas 元素未设置 CSS 缩放(如
width:100%),否则getImageData仍按原始像素尺寸读取,易导致模糊或偏移
完整最小可运行示例
HTML 中放一个 <canvas></canvas> 和一张图片(如 <img id="src" src="photo.jpg">),JS如下:
const img = document.getElementById('src');
const canvas = document.getElementById('myCanvas');
const ctx = canvas.getContext('2d');
<p>img.onload = () => {
canvas.width = img.naturalWidth;
canvas.height = img.naturalHeight;
ctx.drawImage(img, 0, 0);</p><p>const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
const data = imageData.data;</p><p>for (let i = 0; i r + 0.587 g + 0.114 * b;
data[i] = data[i + 1] = data[i + 2] = gray | 0;
}</p><p>ctx.putImageData(imageData, 0, 0);
};</p>前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











