黑白滤镜通过将每个像素的rgb值按加权平均(0.299r+0.587g+0.114b)转为灰度值,并统一赋给r、g、b通道实现,alpha保持不变;需用ctx.getimagedata获取数据、遍历修改后用putimagedata写回。

在 HTML5 的 Canvas 中,ImageData 对象的 data 属性是一个一维 Uint8ClampedArray,按 RGBA 顺序每 4 个元素表示一个像素。要实现黑白(灰度)滤镜,核心是把每个像素的 RGB 值转换为亮度值,再统一赋给 R、G、B 通道,Alpha 保持不变。
获取 ImageData 并遍历像素
先通过 ctx.getImageData(x, y, width, height) 获取图像数据,然后用 for 循环以步长 4 遍历 data 数组:
- 每次取索引
i处的 R(data[i])、i+1处的 G(data[i+1])、i+2处的 B(data[i+2]) - 用加权平均法计算灰度值:常用系数为
0.299 * R + 0.587 * G + 0.114 * B(人眼对绿色最敏感) - 将结果四舍五入为整数,并同时写入
data[i]、data[i+1]、data[i+2] -
data[i+3](Alpha)不改动
完整示例代码
假设 canvas 已加载好图片,执行以下逻辑:
使用 PptxGenJS 和 Python 解析,将结构化的 HTML/CSS 幻灯片内容转换为原生、可编辑的 PowerPoint(.pptx)演示文稿。
const ctx = canvas.getContext('2d');
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
const data = imageData.data;
<p>for (let i = 0; i r + 0.587 g + 0.114 * b);
// 写回三个通道
data[i] = gray; // R
data[i + 1] = gray; // G
data[i + 2] = gray; // B
// data[i + 3] 保持不变(Alpha)
}</p><p>// 将处理后的数据写回画布
ctx.putImageData(imageData, 0, 0);
</p>
注意事项
实际使用中需注意几点:
- 确保图片已完全加载且跨域策略允许读取像素(否则会触发安全异常)
- Canvas 宽高需与原始图片一致,否则 getImageData 可能截断或拉伸
- 若追求性能,可考虑使用
Uint32Array视图一次性读写 32 位像素(需字节序适配),但对黑白滤镜而言常规遍历已足够 - 灰度公式也可简化为平均法
(r + g + b) / 3,但视觉效果略逊于加权法
扩展:快速反色或二值化
基于相同遍历结构,可轻松拓展其他效果:
-
反色:将
r、g、b分别替换为255 - r、255 - g、255 - b - 二值化(黑白点阵):先算灰度,再根据阈值(如 128)设为 0 或 255
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










