canvas 像素操作依赖 imagedata 对象,通过 getimagedata 读取 rgba 数组、直接修改 data 属性、再用 putimagedata 写回;需注意索引计算、uint8clampedarray 自动截断、区域匹配及性能优化。

Canvas 的像素操作主要通过 ImageData 对象实现,核心是 ctx.getImageData() 和 ctx.putImageData() 配合直接读写像素数组。
获取像素数据:用 getImageData 读取 RGBA 数组
调用 ctx.getImageData(x, y, width, height) 返回一个 ImageData 实例,其 .data 属性是一个一维 Uint8ClampedArray,按行优先顺序存储每个像素的 R、G、B、A 值(0–255)。例如 100×100 的画布,共 40000 个字节,索引 i 对应像素位置:
- R → data[i]
- G → data[i+1]
- B → data[i+2]
- A → data[i+3]
其中 i = (y * width + x) * 4
修改像素:直接操作 data 数组
拿到 imageData.data 后可逐个修改值。比如将某个坐标 (x, y) 的像素设为纯红:
- 计算偏移量:
const idx = (y * imageData.width + x) * 4 - 赋值:
data[idx] = 255; // R data[idx+1] = 0; // Gdata[idx+2] = 0; // Bdata[idx+3] = 255; // A(不透明)
注意:Uint8ClampedArray 自动截断超出 [0,255] 的值,无需手动判断。
写回画布:用 putImageData 更新显示
修改完 data 后,必须调用 ctx.putImageData(imageData, dx, dy) 才能在画布上看到效果。参数 dx 和 dy 是目标绘制起点(通常为 0,0),不是偏移量。该操作是“写入”,不会自动清空或缩放,只更新指定区域。
- 确保写入尺寸与 getImageData 获取的尺寸一致,否则可能错位或裁剪
- 频繁操作时避免在循环里反复调用 getImageData/putImageData——先读一次,批量改完再写一次
- 如需实时处理(如滤镜),建议用 offscreen canvas 或 requestAnimationFrame 控制帧率
性能提示:别在每帧都全图读写
大画布(如 1024×768)每次读写约 3MB 数据,直接操作 data 很快,但 getImageData/putImageData 本身开销较大。
- 只处理需要变更的区域,缩小 getImageData 范围
- 用
ctx.createImageData(w, h)创建空白 ImageData,避免从画布读取原始像素(适合生成新图像) - 复杂运算可考虑 Web Workers 搬到后台线程,避免阻塞渲染
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











