Canvas浮雕效果通过像素级差分运算实现:取右侧像素RGB减当前像素RGB再加128,截断至[0,255],跳过最右列,最后写回图像数据。

网页端用 Canvas 实现浮雕效果,核心是局部像素处理:读取原始像素 → 按浮雕算法计算新 RGB 值 → 写回画布。它不是靠 CSS 滤镜,而是对每个像素做数学运算,突出图像边缘、弱化平滑区域。
浮雕算法原理与关键细节
浮雕效果本质是“差分+偏移”:用相邻像素(通常是右侧或下方)的 RGB 值减去当前像素的 RGB 值,再加 128(中性灰),使差异变可见。常见公式为:
- Rnew = Rright − Rcurrent + 128
- Gnew = Gright − Gcurrent + 128
- Bnew = Bright − Bcurrent + 128
注意三点:
- 必须确保不越界——计算右侧像素时,列索引不能等于 width−1;否则跳过该像素或用当前值填充
- 结果需截断到 [0, 255] 范围,可用
Math.max(0, Math.min(255, value)) - 建议后续加一步灰度处理(可选),避免残留彩色噪点,让浮雕更干净
完整实现步骤
按“加载→绘制→读取→遍历→写入”顺序执行:
- 设置图片跨域属性:
img.crossOrigin = 'anonymous'(远程图必需,否则 getImageData 报错) - 用
ctx.drawImage(img, 0, 0)将图完整绘制到 canvas 上 - 调用
ctx.getImageData(0, 0, width, height)获取全部像素数据 - 遍历
data数组,每 4 位一组(R,G,B,A),对每个非最右列像素计算差分值 - 把新 R/G/B 值分别赋给
data[i]、data[i+1]、data[i+2](A 不变) - 最后
ctx.putImageData(imageData, 0, 0)刷新显示
实际代码片段(精简可运行)
以下为关键逻辑节选,可直接嵌入 HTML 中测试:
const img = new Image();
img.crossOrigin = 'anonymous';
img.src = './photo.jpg';
img.onload = () => {
const canvas = document.getElementById('myCanvas');
const ctx = canvas.getContext('2d');
canvas.width = img.naturalWidth;
canvas.height = img.naturalHeight;
ctx.drawImage(img, 0, 0);
<p>const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
const data = imageData.data;</p><p>for (let i = 0; i </p><pre class="brush:php;toolbar:false;">const rightIdx = i + 4; // 右侧像素起始索引
const r = Math.max(0, Math.min(255, data[rightIdx] - data[i] + 128));
const g = Math.max(0, Math.min(255, data[rightIdx + 1] - data[i + 1] + 128));
const b = Math.max(0, Math.min(255, data[rightIdx + 2] - data[i + 2] + 128));
data[i] = r;
data[i + 1] = g;
data[i + 2] = b;
}
ctx.putImageData(imageData, 0, 0); };
提升效果与体验的小技巧
浮雕效果容易显得生硬或带杂色,可叠加优化:
- 改用“右下角像素”替代“右侧像素”,增强立体感(需同时检查 x 和 y 边界)
- 在差分后做简单灰度融合:比如
gray = 0.299*r + 0.587*g + 0.114*b,再令 R=G=B=gray - 若原图较大,先缩放至 50% 再处理,加快计算速度且不影响视觉辨识度
- 导出结果图?记得用
canvas.toDataURL('image/png')—— 这次导出的是已应用浮雕的真实像素,不是原始图











