每一个十字绣图纸生成器内部都有这样一个循环:对这个像素的颜色,找出最接近的 DMC 绣线。听起来像是最无聊的那部分。实际上,很多图纸就是在这里悄悄出的问题。
最朴素的做法是在 RGB 里衡量「最接近」——把红、绿、蓝当作三根轴,选直线距离最小的那根线。这是一行代码的事,而它出错的频率高到不能忽视。
RGB 距离为什么会撒谎
RGB 描述的是屏幕如何发光,不是眼睛如何感知。这个空间不是感知均匀的:RGB 里相等的距离,看起来的差别并不相等。
在制图中有两个后果反复出现:
绿色被高估,蓝色被低估。 人眼对绿色变化的敏感度远高于蓝色。而在 RGB 里三个通道权重相同,于是这个度量会把一个你几乎看不出来的蓝色偏移,当成和一个显而易见的绿色偏移一样重要。天空和阴影因此吃亏最多。
明度和色相被搅在一起。 在 RGB 里,从中灰走向一个饱和色,和从中灰走向一个更浅的灰,距离可能是一样的。但把一个色号换成略浅一点的同色,在绣线上几乎看不出来;换成错误的色相,就非常刺眼。RGB 无法表达这种优先级差异,于是它做出错误的取舍——经常选出一根明度对、色相明显错的线。
最典型的失败是皮肤。用 RGB 匹配肤色,会去够一个数值上很近、感知上很怪的粉色或灰色,于是脸上长出一块淤青。
Lab 有什么不同
CIELAB 就是为这个问题设计的。它把颜色拆成三根按人类感知选定的轴:
- L* —— 明度,从黑到白
- a* —— 绿到红
- b* —— 蓝到黄
关键性质是它近似感知均匀:在这个空间的任何位置,同样的距离都对应大致相同的可见差异。这意味着「最近」终于等于「看起来最像」,而不是「数值上相近」。
我们把图像颜色和每一个 DMC 色号都转换到 Lab,然后在那里匹配。同样的循环,同样的开销,换了一个空间——得到一个可以量化的更好答案。
你真正能看到差别的地方
这个差别在画面上不是均匀分布的,它集中在人们在意的位置:
皮肤。 收益最大的一处。Lab 让皮肤从阴影到高光都待在正确的色相路径上,脸保持温暖,不再出现 RGB 匹配产出的那种绿斑或紫斑。
阴影和接近中性的颜色。 深色在 RGB 里是被压缩的——很多肉眼可辨的深色,数值上挤在一起。Lab 把它们摊开,于是阴影能保住它那一点点偏蓝或偏棕的性格,而不是塌成一片通用的深灰。
树叶。 绿色正是 RGB 过度敏感造成最大破坏的地方。Lab 能正确区分黄绿和蓝绿,而这就是「一棵有纵深的树」和「一团扁平绿块」之间的差别。
天空和渐变。 平滑过渡会选出更均匀的一梯色号,在不多花颜色的前提下减少可见的色带。
它还能省颜色
这是实打实的回报。因为每一根选中的线都是真正更好的匹配,达到同样的视觉还原度需要的线更少。
如果你的度量总是选出略微不对的线,唯一的补偿方式就是不断加线,直到碰上一根足够接近的。而一开始就匹配得好,意味着一张 22 色的 Lab 匹配图纸,可以和 30 色的 RGB 匹配图纸一样有说服力。这是八绞线和一张更短的色卡,来自算术的改变,而不是你预算的改变。
它解决不了什么
感知匹配不是魔法,把边界说清楚是值得的:
- DMC 色卡是有限的。 大约 500 个色号,分布还不均匀。色彩空间里有些区域——明亮的青色、某些饱和的紫色——用任何度量都根本找不到接近的线。
- 它治不了彩色噪点。 彩色噪点是空间问题,不是配色问题。那个请看绣线预算和宠物肖像那两篇。
- 屏幕不是绣线。 你的显示器在发光,绣线是在反光,还带着光泽和质感。一个完美的 Lab 匹配,绷在绣圈上看仍会略有不同,通常是稍深、稍柔和。
- 染缸批次有差异。 你买到的那一绞实物,并不精确等于色卡上的数值。
为什么值得做
因为它免费。转换到 Lab 每个颜色只需几微秒,而且每套色板只做一次。一个图纸生成器没有任何理由使用更差的那个度量,除了更差的那个更好写。
所以 StitchCraft 在 Lab 里匹配,图纸也因此少用几绞线。
