canvas动态图像锐化需用3×3卷积核逐像素加权计算,关键在准确遍历、边界处理和避免原地覆盖;先通过crossorigin加载图像并获取imagedata,再用新数组存储结果,最后putimagedata一次性写回。

Canvas像素操作实现动态图像锐化,核心是用卷积核对每个像素做加权邻域计算,再归一化输出。关键不在“加滤镜”,而在准确遍历、边界处理和避免原地覆盖。
准备图像并获取原始像素数据
先确保图片已加载且无跨域问题:给 加 crossOrigin="anonymous" 属性;等 onload 触发后,用 drawImage 绘制到 canvas 上,再调用 getImageData(0, 0, width, height) 获取 RGBA 数据。注意:data 是一维 Uint8ClampedArray,每 4 个值为一个像素(R、G、B、A),索引公式为 (y × width + x) × 4。
应用3×3锐化卷积核并逐像素计算
典型锐化核如 [[0, -1, 0], [-1, 5, -1], [0, -1, 0]],中心权重为正,周围为负。对每个像素 (x, y),需遍历核中 9 个位置:
将调研报告、方案对比、数据分析、需求梳理、会议纪要、设计说明、代码评审、学习笔记等任务产物输出为可在浏览器直接打开的单文件 HTML,替代 Markdown 作为最终交付物。Markdown 在信息密度、视觉清晰度和可分享性上已跟不上 AI 产物的丰富度,HTML 能同时承载排版、表格、SVG 等。
- 计算邻点坐标:nx = x + kx - 1,ny = y + ky - 1(因 pad = 1)
- 检查 nx、ny 是否在画布范围内,越界则跳过或设为边缘值
- 对 R/G/B 通道分别累加:sumR += data[(ny × width + nx) × 4] × kernel[ky][kx]
- 结果需截断到 [0, 255] 区间,避免溢出
写回新数据并防止边改边读出错
不能直接修改原 imageData.data 数组——否则后续像素会读到已被覆盖的中间值。正确做法是:
- 创建新数组:const newData = new Uint8ClampedArray(data.length)
- 遍历时只读原 data,所有计算结果写入 newData
- 全部算完后,用 putImageData 一次性写回 canvas
可选增强:支持亮度补偿与实时调节
锐化后图像可能偏亮,可在卷积和基础上减去一个补偿值(如 0~20),或让核总和归一化为 1(本例核和为 1,无需额外缩放)。若想动态调节强度,可将核值乘以一个系数(如 1.2 增强,0.8 减弱),再重新归一化。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










