canvas图片色调转换核心是依据人眼敏感度加权灰度(gray=0.299×r+0.587×g+0.114×b)、rgb通道独立反色(r'/g'/b'=255−r/g/b)及线性拉伸对比度(centered=value−128, adjusted=centered×contrast+128),均需保持alpha不变且防越界。

Canvas 实现图片色调转换,核心是直接读取并修改每个像素的 R、G、B 值,不依赖预渲染图或外部库。关键不在“换颜色”,而在“有依据地改数值”——比如灰度不是简单平均,反转不是随意减法,对比度调整必须防越界。
灰度转换:按人眼敏感度加权计算
人眼对绿色最敏感,红色次之,蓝色最弱。直接用 (R+G+B)/3 会丢失明暗层次,看起来发灰发闷。
- 正确公式:gray = R × 0.299 + G × 0.587 + B × 0.114
- 用 | 0 替代 Math.floor() 提升性能(位运算更快)
- 将算出的 gray 同时赋给 R、G、B 三个通道,Alpha 保持原值不变
颜色反转:RGB 各通道独立取反
反转本质是关于 127.5 对称,操作极简且天然不越界——因为 0→255、128→127、255→0,全在 0–255 范围内。
用户要生成可打印的中文字帖/练习纸、导出多页 A4 PDF 报告,或把 SVG 设计稿零误差还原到 Canvas 时使用。本技能是「Canvas 内容工厂闭环」的总控,编排:网格渲染引擎(13 种教育网格+拼音标注) → 多页 PDF 导出(A4 合成) → SVG 精准复刻(坐标误差<0.001px)。触发词:生成字帖、练习纸、导出 PDF、SVG 转 Canvas、印刷级还原、A4 报告、米字格田字格。
- R' = 255 − R
- G' = 255 − G
- B' = 255 − B
- Alpha 不参与运算,原样保留
对比度调节:线性拉伸 + 边界截断
不是简单乘系数,而是先中心化再缩放最后还原,避免整体偏色或死黑死白。
- 对每个通道:centered = value − 128
- adjusted = centered × contrast + 128(contrast > 1 增强,
- 必须用 Math.min(255, Math.max(0, adjusted)) 截断,否则会溢出
实际处理时的关键细节
很多效果“写出来就报错”或“显示空白”,往往卡在几个实操环节:
- 图像必须已完整绘制到 canvas 上,再调 getImageData,否则读到的是空数据
- 跨域图片需提前设置 img.crossOrigin = '',否则 getImageData 抛安全异常
- canvas 的 width/height 属性必须显式设置(不能只靠 CSS),否则坐标映射失准
- 遍历 data 数组时步长为 4(R、G、B、A),别漏掉 Alpha 或错位修改










