html5 canvas图片灰度处理需先加载图片并设canvas宽高为naturalwidth/height,跨域图加crossorigin="anonymous";用getimagedata获取像素,按0.299r+0.587g+0.114b加权计算灰度值并取整,赋给rgb通道,保留alpha;最后putimagedata写回,注意性能优化。

HTML5 Canvas 实现图片黑白(灰度)处理,核心是获取像素数据、按加权公式计算灰度值、再写回画布。关键不在“变黑变白”,而在模拟人眼感知的明暗层次,避免简单平均导致发灰或失真。
确保图片正确加载并绘制到 Canvas
Canvas 滤镜必须等图片完全加载后执行,否则 getImageData 会读取空白区域。
- 设置 canvas.width 和 canvas.height 为图片原始尺寸(用
img.naturalWidth/img.naturalHeight),不能只靠 CSS 缩放 - 跨域图片需添加
crossOrigin="anonymous"属性,否则 getImageData 报安全错误 - 绘制前确认 canvas 已有明确宽高,否则可能读取到 0×0 区域
用 getImageData 获取并处理像素数据
ImageData.data 是一个 Uint8ClampedArray,每 4 个连续值代表一个像素的 R、G、B、A(0–255)。遍历时步长为 4,跳过 alpha 参与计算但保留其原值。
- 推荐使用加权灰度公式:gray = 0.299 × R + 0.587 × G + 0.114 × B(YUV 亮度分量,视觉更自然)
- 结果需转为整数,可用
Math.round(gray)或位运算gray | 0 - 将同一 gray 值同时赋给 data[i]、data[i+1]、data[i+2],保持 alpha(data[i+3])不变
用 putImageData 写回并注意性能细节
处理完全部像素后,调用 putImageData 渲染结果。大图(如 >1000×1000)易造成主线程卡顿。
- 确保 putImageData 的宽高参数与 getImageData 一致,否则图像错位或裁剪
- 避免在循环内创建对象、调用函数或访问 DOM;缓存
data.length和data引用 - 对高清图可考虑降采样处理(先缩至 50%,处理后再双线性放大),或用 requestIdleCallback 分块执行
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











