html5中可通过canvas的getimagedata和putimagedata配合高斯核卷积实现纯前端逐像素高斯模糊,支持自定义σ与核尺寸,适用于毛玻璃、图像预处理等场景;需注意跨域、边界处理、性能优化及封装复用。

在 HTML5 中,可以通过 Canvas 的 getImageData 和 putImageData 配合高斯核卷积计算,实现纯前端的图片高斯模糊效果。这不是调用 CSS filter: blur(),而是真正逐像素计算,可控性强、可定制核大小与标准差,适合需要精确模糊(如毛玻璃背景、图像预处理)的场景。
获取图像数据并准备像素缓冲区
先将图片绘制到 <canvas></canvas> 上,再读取原始像素数据。注意需满足跨域策略(本地测试建议用本地服务器启动,避免 CORS 报错):
- 创建与图片等尺寸的 canvas,用
ctx.drawImage(img, 0, 0)绘制 - 调用
ctx.getImageData(0, 0, width, height)获取ImageData对象 - 其
.data是长度为width × height × 4的 Uint8ClampedArray,按 RGBA 顺序排列 - 为避免原地修改干扰计算,建议申请新数组:
const output = new Uint8ClampedArray(data.length)
构造高斯核并实现二维卷积
高斯模糊本质是图像与高斯核做卷积。标准差 σ 决定模糊强度,核半径通常取 Math.ceil(3 * σ)(覆盖 99.7% 权重)。例如 σ=2 时,常用 5×5 核:
- 生成一维高斯权重数组:
const kernel = []; for (let x = -r; x - 归一化:求和后每个元素除以总和,保证亮度不变
- 二维核可分离:先横向卷积(每行独立),再纵向卷积(每列独立),大幅降低复杂度(从 O(n⁴) → O(n³))
- 边界处理推荐「镜像扩展」或「复制边缘」,避免黑边;不建议直接跳过边界(会裁剪)
优化性能的关键实践
纯 JS 像素遍历在大图上易卡顿,必须优化:
- 使用
Float32Array存储中间结果(比 Uint8ClampedArray 运算快,且避免反复类型转换) - 分离卷积时,横向处理用「行优先」内存访问,纵向改用「列优先 + 步长 width」,提升缓存命中率
- 对宽高 > 1000px 的图,考虑降采样(如 0.5 倍)模糊后再上采样,视觉差异小但性能提升明显
- 避免在主线程长时间运行:可用
setTimeout分块处理,或迁移到 Web Worker(需传入 ImageData.buffer)
写回 canvas 并渲染结果
计算完成后,将输出数组封装为新 ImageData 并写回画布:
const result = new ImageData(output, width, height);ctx.putImageData(result, 0, 0);- 若需叠加原始图(如毛玻璃效果),可先
ctx.globalAlpha = 0.8绘制模糊层,再绘制原图 - 注意:
putImageData不受globalCompositeOperation影响,是直接覆写像素
不复杂但容易忽略细节。核心是分离卷积 + 归一化核 + 边界处理,跑通后调整 σ 就能控制模糊程度。实际项目中,可封装成 gaussianBlur(ctx, imageData, sigma) 函数复用。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











