canvas实现灰度和反转特效需先确保图像就绪、尺寸对齐、跨域合规;灰度用加权平均(0.299r+0.587g+0.114b),反转直接取反(255−rgb),alpha通道均保持不变。

Canvas 实现灰度和反转特效,核心是操作像素数据——先用 getImageData() 读取,再逐像素计算,最后用 putImageData() 写回。关键不在算法多复杂,而在图像就绪、尺寸对齐、跨域合规这三步没出错。
确保图像可安全读取
图像未加载完成或跨域受限时,getImageData() 会静默失败或抛 SecurityError:
- 图片必须监听
img.onload,不能仅靠window.onload - 画布的
width和height必须设为图片原始尺寸(img.naturalWidth/img.naturalHeight),否则坐标偏移导致裁切或空白 - 跨域图片需提前设置
img.crossOrigin = 'anonymous',且服务端响应头含Access-Control-Allow-Origin
灰度处理:用加权平均更准
人眼对绿光最敏感,对蓝光最不敏感,直接取平均((r+g+b)/3)会发灰发闷。标准做法是:
- 对每个像素,取
data[i](R)、data[i+1](G)、data[i+2](B) - 计算
gray = (r * 0.299 + g * 0.587 + b * 0.114) | 0(位运算比Math.floor略快) - 把
gray同时赋给data[i]、data[i+1]、data[i+2];data[i+3](Alpha)保持不变
反转处理:RGB 各通道直接取反
反转本质是颜色值关于 127.5 对称,操作极简且无越界风险:
-
data[i] = 255 - data[i](R → R′) -
data[i+1] = 255 - data[i+1](G → G′) -
data[i+2] = 255 - data[i+2](B → B′) - Alpha 通道不参与,原值保留
合并使用与性能提醒
灰度和反转可叠加(先灰度再反转,或反之),顺序不同效果略有差异;但要注意:
-
putImageData()是同步重绘操作,避免在requestAnimationFrame循环中高频调用 - 如需实时视频帧处理,建议用
OffscreenCanvas或移交Web Worker计算 - 调试时可打印
data.subarray(0, 12)查看前 3 个像素的 RGBA 值,验证逻辑是否生效











