如何在Canvas中实现阴影/高光增强、冷暖色调调整等简单像素操作?
Canvas 阴影/高光、冷暖色调调整实现方案
1. 冷暖色调调整
实现原理
冷暖色调调整核心是修改红、蓝通道的占比:暖色调增强红色通道、减弱蓝色通道;冷色调反之。调整时对RGB值做钳位,避免超出0-255范围产生色偏。
参数warmth取值范围建议设为[-50, 50],负值为冷色调,正值为暖色调。
实现代码
var imageData = context.getImageData(0, 0, img.width, img.height); var data = imageData.data; var warmth = 20; // 可调参数:正暖负冷,范围-50~50 for(var i = 0; i < data.length; i += 4) { var r = data[i]; var g = data[i + 1]; var b = data[i + 2]; // 基础冷暖调整 r = Math.min(255, Math.max(0, r + warmth)); b = Math.min(255, Math.max(0, b - warmth)); data[i] = r; data[i + 1] = g; data[i + 2] = b; } context.putImageData(imageData, 0, 0);
如果要避免暗部/亮部调整过度,可以给调整值叠加亮度权重,效果更自然:
// 计算像素标准亮度 var luma = 0.299 * r + 0.587 * g + 0.114 * b; var adjust = warmth * (luma / 255); r = Math.min(255, Math.max(0, r + adjust)); b = Math.min(255, Math.max(0, b - adjust));
2. 阴影/高光调整
实现原理
首先通过标准灰度公式计算每个像素的亮度值,区分阴影(低亮度)、高光(高亮度)区域:
- 阴影调整仅作用于低亮度像素,用于提升/压低暗部细节
- 高光调整仅作用于高亮度像素,用于压暗/提亮亮部细节
通过平滑权重控制调整强度,避免不同亮度区域之间出现硬过渡边。参数shadows、highlights建议取值范围[-100, 100],正值为提亮,负值为压暗。
实现代码
var imageData = context.getImageData(0, 0, img.width, img.height); var data = imageData.data; var shadows = 30; // 阴影调整参数:正提暗负压暗 var highlights = -20; // 高光调整参数:正提亮负压暗 for(var i = 0; i < data.length; i += 4) { var r = data[i]; var g = data[i + 1]; var b = data[i + 2]; // 计算像素标准亮度 var luma = 0.299 * r + 0.587 * g + 0.114 * b; // 计算阴影、高光调整平滑权重 var shadowWeight = Math.pow((255 - luma) / 255, 2); var highlightWeight = Math.pow(luma / 255, 2); // 计算总调整量 var shadowAdjust = shadows * shadowWeight * 0.5; var highlightAdjust = highlights * highlightWeight * 0.5; var totalAdjust = shadowAdjust + highlightAdjust; // 应用调整并钳位 r = Math.min(255, Math.max(0, r + totalAdjust)); g = Math.min(255, Math.max(0, g + totalAdjust)); b = Math.min(255, Math.max(0, b + totalAdjust)); data[i] = r; data[i + 1] = g; data[i + 2] = b; } context.putImageData(imageData, 0, 0);
如果需要更好的色彩保留效果,可以先将RGB转换为HSL色彩空间调整亮度通道,再转回RGB,遍历处理的逻辑和上述结构完全一致。
内容的提问来源于stack exchange,提问作者Noah Wilson
相关产品推荐
相关产品推荐

