Canvas图片马赛克本质是重绘像素块而非调滤镜,核心为离散化采样+确定性填充,需禁用浏览器插值以获得硬边效果;步骤包括同源加载、设定粒度、坐标遍历、取左上角像素填色或drawImage缩放+imageSmoothingEnabled=false;局部打码需限定区域并校准坐标;避免putImageData和平均色计算误区。

Canvas 实现图片马赛克不是调滤镜,而是“重绘像素块”——把图像切成小格子,每格只保留一个颜色,再放大填满。关键不在模糊,而在离散化采样+确定性填充,禁用浏览器插值才能出硬边效果。
核心步骤:加载→采样→填色
必须先将图片绘制到 canvas 上(确保尺寸匹配),再通过 getImageData 读取像素数据。注意:图片必须同源,本地双击打开(file://)会因跨域报错,需起本地服务(如 python3 -m http.server)。
- 设定马赛克粒度,例如
blockSize = 12 - 循环遍历坐标:x 从 0 到图片宽,步长为 blockSize;y 同理
- 对每个块,读取左上角像素(
data[(y * width + x) * 4])获取 R、G、B 值 - 用
ctx.fillStyle = `rgb(${r},${g},${b})`+fillRect(x, y, blockSize, blockSize)填满该区域
更高效方案:drawImage 缩放 + 关闭平滑
比逐像素计算平均值更快,也更易控制视觉硬度。原理是把小区域“拉伸”成大块,靠浏览器最近邻插值实现块状效果。
把任意文章或文档内容转换成精美的全屏翻页 HTML 演示文件(幻灯片风格)。当用户发来一篇文章、文档链接、Markdown 内容、或粘贴的文本,并且希望生成演示用的 HTML 时触发。支持任意内容来源:iWiki 链接、KM 链接、本地文件路径、直接粘贴的文本。生成的 HTML 文件保存到本地工作区,并通过企微直接发送给用户。触发词示例:帮我把这篇文章做成PPT、转成演示文档、生成HTML幻灯片、做个演示、转成可以演示的格式、article to deck、make a slide。
- 提前设置
ctx.imageSmoothingEnabled = false(否则边缘发虚) - 对每个马赛克单元,调用:
ctx.drawImage(canvas, x, y, blockSize, blockSize, x, y, blockSize * 4, blockSize * 4) - 只需一次 drawImage,无需 getImageData 或 fillRect,性能更好
局部打码:限定区域 + 坐标校准
只处理人脸或敏感区域,不能全图重绘。重点在“范围控制”和“坐标映射”。
- 定义目标区域:例如
{x: 120, y: 80, width: 60, height: 60} - 循环时限定 y 起始/结束、x 起始/结束,只覆盖该矩形内坐标
- 若 canvas 有 CSS 缩放(如 width:100%),鼠标坐标需用
getBoundingClientRect()校准后再映射为 canvas 像素坐标 - 读取像素时,直接用
ctx.getImageData(roi.x, roi.y, roi.width, roi.height),避免整图读取开销
常见误区提醒
putImageData 不能直接做马赛克——它只是把内存里原始像素原样贴回去,不会放大也不会重复填充。所谓“降采样后 put 回去”,实际仍是逐像素写入,得不到块状效果。真正需要的是循环 + fillRect 或 多次 drawImage 缩放。
- 别依赖平均色:取左上角像素更简洁、边界更锐利;算平均值适合柔和过渡需求
- 别忽略 canvas 坐标系:DOM 坐标 ≠ canvas 像素坐标,尤其响应式页面中必须校准
- 别在非同源图上调用 getImageData:会抛 SecurityError,可考虑 proxy 中转或服务端预处理
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










