canvas实现图片局部马赛克的核心是只对指定区域采样重绘,关键在精准定位、分块处理、逐块填色或缩放绘制;需解决跨域限制,通过同源部署或cors头配合crossorigin属性;再划分马赛克单元并选择取色fillrect或drawimage缩放两种方式实现。

Canvas 实现图片局部马赛克,核心是“只对指定区域采样重绘”,不碰其他像素。关键不在全局模糊,而在精准定位、分块处理、逐块填色或缩放绘制。
必须先确保图片能读取像素数据
跨域图片(如 src 是外链)或本地双击打开的 file:// 页面,调用 getImageData() 会直接报 SecurityError。解决办法只有两个:
- 图片放在同源服务器下(比如和 HTML 同域名)
- 服务端给图片响应头加 Access-Control-Allow-Origin: *,且 JS 加载时设置 img.crossOrigin = 'anonymous'
确定局部区域并划分马赛克单元
假设你要对图片上一个矩形区域(x=100, y=80, width=200, height=120)打码,马赛克粒度设为 16px:
- 用 ctx.getImageData(x, y, width, height) 读取该区域原始像素
- 按 16×16 划分单元:横向循环 i 从 0 到 width-1 步长 16,纵向 j 从 0 到 height-1 步长 16
- 每个单元实际坐标是 x+i, y+j,别忘了加上区域左上偏移
两种主流实现方式选其一
方式一:取色 + fillRect(硬边清晰,推荐)
- 对每个 16×16 单元,读取左上角像素(或算平均 RGB)得到 color
- 用 ctx.fillStyle = `rgb(r,g,b)` + ctx.fillRect(x+i, y+j, 16, 16)
- 效果干脆,无插值,适合隐私遮挡
方式二:drawImage 缩放(更高效,需关抗锯齿)
- 提前设 ctx.imageSmoothingEnabled = false
- 对每个单元,执行:
ctx.drawImage(canvas, x+i, y+j, 16, 16, x+i, y+j, 64, 64)
(把 16×16 区域拉伸到 64×64,浏览器用最近邻插值,形成方块感) - 比逐像素计算快,尤其大图
注意别踩这些坑
局部马赛克容易出错的地方:
- 没重设 canvas.width/height 导致 drawImage 尺寸错乱——建议每次加载新图后显式设置
- 忘记把鼠标坐标转成 canvas 坐标(要考虑 canvas 的 CSS 缩放、border、padding)
- 用 putImageData 直接放大原始数据——它只是贴图,不会重复填充,不能替代 fillRect 或 drawImage
- 清除马赛克时直接清画布——应备份原图 canvas,清除时用 getImageData + putImageData 把原区域贴回去
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











