Canvas图像像素操作通过getImageData读取RGBA数据,遍历修改R/G/B值实现反色(255减原值)和高对比度(以128为中心缩放),Alpha保持不变,需确保图片加载完成、canvas尺寸匹配及跨域设置,最后用putImageData写回。

Canvas 图像像素操作实现反色与高对比度特效,核心是通过 getImageData 读取原始 RGBA 数据,遍历每个像素的 R、G、B 值进行数学变换,再用 putImageData 写回画布。整个过程不依赖服务器、不加载新资源,所有计算在浏览器内存中完成。
反色(负片)效果:逐通道取反
反色的本质是将每个颜色分量关于 127.5 对称翻转,即用 255 减去当前值。Alpha 通道保持不变,避免影响透明区域。
- 遍历
data数组,步长为 4(R、G、B、A 各占 1 字节) - 对每组前三个元素分别执行:
data[i] = 255 - data[i](红)、data[i+1] = 255 - data[i+1](绿)、data[i+2] = 255 - data[i+2](蓝) - 跳过第四个元素(
data[i+3]),保留原始透明度 - Uint8ClampedArray 自动处理越界,255−0=255、255−255=0,无需额外判断
高对比度效果:以灰度中心线拉伸
高对比度不是简单增强饱和度,而是扩大明暗差异。标准做法是以 128 为基准点,将每个通道值减去 128 后乘以对比度系数,再加回 128。
- 先计算中心偏移:
centered = value - 128 - 应用缩放:
adjusted = centered * contrast + 128,其中contrast > 1表示增强(如 1.3)、表示减弱 - 对 R、G、B 三个通道分别独立计算,A 不参与
- 结果需截断到 [0, 255] 范围——Uint8ClampedArray 会自动完成,但若手动处理建议用
Math.min(255, Math.max(0, adjusted))
关键执行前提不能漏
算法写得再准,环境没配好也会报错或白屏。
- 图片必须完全加载后才调用
drawImage,否则getImageData返回空白或报错 - canvas 宽高要显式设为图片的
img.width和img.height,否则缩放会导致像素错位 - 跨域图片(如 CDN 地址)必须设置
img.crossOrigin = "anonymous",否则触发安全策略拦截 - 修改完
data数组后,必须调用putImageData,Canvas 不会自动同步内存变化
性能优化小提示
如果只处理局部区域(比如只增强人像脸部),可以用 putImageData 的脏区参数,减少重绘范围:
ctx.putImageData(imgData, dx, dy, dirtyX, dirtyY, dirtyWidth, dirtyHeight)- 实际绘制位置是
(dx + dirtyX, dy + dirtyY),不是整图左上角 - 适合做实时预览或分块处理,能明显降低渲染开销


















