Canvas浮雕滤镜通过getImageData读取像素、手动应用3×3卷积核(如[1 1 0; 1 0 -1; 0 -1 -1])、加128偏移并截断至0–255,再用putImageData写回实现,全程内存操作,支持实时处理。
Canvas像素卷积运算实现浮雕滤镜,核心是用
读取像素,手动应用3×3浮雕卷积核,再用
写回——整个过程在内存中完成,不依赖外部库,适合实时处理。
获取图像数据并准备Canvas上下文
先确保图像已加载完成(避免跨域问题),然后将图像绘制到
上,再获取原始像素数据:
创建足够大的
(宽高与图像一致),调用
用
把图像画进去
立即执行
,得到含
数组的ImageBuffer对象
是Uint8ClampedArray,每4个元素代表一个像素的RGBA值(R、G、B、A各占1字节)
应用浮雕卷积核(Emboss Kernel)
标准浮雕效果常用如下3×3卷积核:
立即学习
“
前端免费学习笔记(深入)
”;
Canva
使用Canva可画,轻松创建专业设计
下载
实际更常用中心对称增强版(突出边缘明暗对比):
计算时注意:
遍历每个非边界像素(即x从1到width−2,y从1到height−2)
对每个像素(x,y),取出其周围3×3区域共9个像素的RGBA值
仅对R、G、B通道分别做加权求和(A通道通常保持255不变)
结果加上128偏移(避免负值变黑,让灰度中心落在128附近),再用
截断到0–255
写回像素并渲染
卷积计算完后,直接更新
数组对应位置的值,再写回Canvas:
修改
中每个像素的R/G/B分量(索引为
)
A分量(索引+3)建议设为255(保持不透明)
调用
一次性刷新画面
如需实时处理视频帧,可将上述流程放入
循环中,配合
元素的
性能优化与注意事项
纯JS逐像素操作在高分辨率图像上可能卡顿,可针对性优化:
限制处理区域:只处理可视区或缩略尺寸(例如先缩放到400px宽再滤镜)
跳过Alpha通道计算:若图像无透明需求,可只处理RGB,省去25%运算
使用
视图批量读取RGBA(每项为一个32位整数),比四次单字节访问稍快
避免在循环中反复创建数组或对象,复用
和临时缓存数组
移动端注意关闭抗锯齿:
,防止drawImage引入模糊干扰卷积结果
getImageDataputImageDatacanvasgetContext('2d')ctx.drawImage(img, 0, 0)ctx.getImageData(0, 0, width, height)datadata[ 1 0 0 ]
[ 0 0 0 ]
[ 0 0 -1 ][ 1 1 0 ]
[ 1 0 -1 ]
[ 0 -1 -1 ]Math.max(0, Math.min(255, value))imageData.dataimageData.data(y * width + x) * 4 + 0/1/2ctx.putImageData(imageData, 0, 0)requestAnimationFramevideodrawImage(video, ...)Uint32ArrayimageDatactx.imageSmoothingEnabled = false