HTML5 Canvas实现像素化需先用drawImage缩放至小画布并设ctx.imageSmoothingEnabled=false,再等比放大绘制回目标canvas;或用getImageData手动取像素块均值后putImageData填充。

HTML5 Canvas 如何用 getImageData 实现像素化
像素化本质是把图像按固定尺寸分块,每块用左上角(或平均)像素颜色填充整块。Canvas 的 getImageData 和 putImageData 是最直接可控的方式,不依赖 CSS 滤镜或 WebGL,兼容性好且逻辑透明。
关键不是“加滤镜”,而是“重采样+色块填充”。常见错误是直接缩放再放大(导致模糊或抗锯齿干扰),或对每个像素单独操作(性能爆炸)。
- 先用
ctx.drawImage把原图绘制到一个离屏canvas(尺寸设为原始宽高 / 像素尺寸,向下取整) - 再将该小画布等比放大绘制回目标 canvas,
imageSmoothingEnabled = false必须设为 false,否则浏览器会插值模糊 - 像素尺寸建议取 2–16 的整数;太小看不出效果,太大易失真
ctx.imageSmoothingEnabled = false 为什么必须显式关闭
Canvas 默认开启图像平滑(即双线性插值),即使你画的是整数倍缩放,也会软化边缘、破坏像素块的硬边界。这个开关在 Chrome/Firefox/Edge 中默认为 true,Safari 也一样——它不看你的缩放是否为整数,只看是否调用了 drawImage。
容易被忽略的是:该属性作用于**当前上下文**,且**每次创建新 canvas 或重置 ctx 都会恢复默认值**。
立即学习“前端免费学习笔记(深入)”;
- 必须在
drawImage前设置:ctx.imageSmoothingEnabled = false - 若使用多个 canvas(如离屏 + 主屏),每个 ctx 都要单独设置
- 设置后不影响
getImageData数据读取,只影响绘制时的采样行为
用 createImageData 手动构造像素块的适用场景
当需要精确控制每个色块颜色(比如取均值、中位数、或加噪),而不是简单缩放时,就得手动操作像素数据。这时绕不开 getImageData → 处理 data 数组 → putImageData。
性能敏感点在于:data 是一维 Uint8ClampedArray,长宽需自己换算;直接遍历全部像素 O(n²) 很慢,应按像素块步进。
- 假设像素尺寸为
pixelSize = 4,则外层循环:x 从 0 到 width 步长 4,y 同理 - 每块内取 (x, y) 点的 r/g/b/a 值(
data[(y * width + x) * 4]),赋给该块所有像素 - 避免在循环里反复调用
putImageData,应一次性写完再提交
CSS filter: pixelate() 不存在,别被误导
目前(2024)没有任何浏览器支持 filter: pixelate(8px) 这类语法。网上所谓“CSS 像素化”教程,实际是用 transform: scale() 配合低分辨率图,或用 SVG + 模拟,本质都不是实时 Canvas 滤镜。
如果你在 React/Vue 项目里封装像素化组件,优先走 Canvas 方案;若强行用 CSS,会遇到 DPR 适配问题、截图空白、无法与其它 Canvas 绘制叠加等问题。
真正难的不是实现,而是处理 canvas 的 devicePixelRatio 缩放、跨域图片限制、以及大图下 getImageData 的内存占用——这些不在基础像素化逻辑里,但上线前一定会撞上。










