要了解您需要的矩阵,您必须清楚地定义开始的内容、最终的结果以及 colour matrix filter 的工作原理。
矩阵有五列四行。每行代表一个输出数字:R、G、B、A。这些列代表您的输入 RGBA 和一个常数 1。您可以通过将行中的每个值相加乘以相应的输入值来计算每一行的输出值。
输入和输出数字都标准化为 0-1 范围,因此您不必担心将所有内容都乘以 256。
所以对于您示例中的矩阵:
/*R G B A 1 */
0 0 0 0 0 // R = 0*R + 0*G + 0*B + 0*A + 0
1 1 1 1 0 // G = 1*R + 1*G + 1*B + 1*A + 0
0 0 0 0 0 // B = 0*R + 0*G + 0*B + 0*A + 0
0 0 0 1 0 // A = 0*R + 0*G + 0*B + 1*A + 0
它采用输入颜色,将所有四个通道 (RGBA) 相加,然后将结果设为绿色通道。红色和蓝色通道为零,Alpha 通道没有改变。因此,您的图片最终的黑色区域仍然是黑色,但所有彩色/灰色/白色/透明区域都会转换为绿色阴影。
这当然不是你想要的。您希望黑色区域为一种颜色,白色区域为另一种颜色,所有灰色区域介于两者之间。
要使黑色区域具有某种颜色,您必须设置矩阵的常数因子参数。黑色的输入 RGB 值将为零,因此此时它们不考虑在内。
如果您的 colour2(您想在单色图像中用于黑色的值)是 (r2, g2, b2),那么这就是您的常数因子必须是:
/*R G B A 1 */
? ? ? 0 r2 // R = ?*0 + ?*0 + ?*0 + 0*0 + r2 = r2
? ? ? 0 g2 // G = ?*0 + ?*0 + ?*0 + 0*0 + g2 = g2
? ? ? 0 b2 // B = ?*0 + ?*0 + ?*0 + 0*0 + b2 = b2
0 0 0 1 0 // A = 1*A
当然,上述矩阵会将 任何 输入颜色转换为该输出颜色,因为它不考虑输入 RGBA 值中的任何内容。要获得您想要的渐变,您需要白色区域——R、G 和 B 的输入值为 1 的区域,最终得到您的 colour1,我将其写为 (r1, g1, b1)。
现在,为了让事情更容易一些,请记住,对于灰度图像,任何点的 R、G 和 B 值都是相等的。所以我们可以只使用其中任何一个值作为输入,而忽略其他值。因此,如果我们只是为每个通道设置 R 因子,当输入值为白色时,输入 R 等于 1,方程为
/*R G B A 1 */
? 0 0 0 r2 // R = ?*1 + r2 = r1
? 0 0 0 g2 // G = ?*1 + g2 = g1
? 0 0 0 b2 // B = ?*1 + b2 = b1
0 0 0 1 0 // A = 1*A
简单代数告诉你,为了使这些方程有效,你需要用 colour1 和 colour2 值之间的差异来替换问号:
/* R G B A 1 */
(r1-r2) 0 0 0 r2 // R = (r1-r2)*1 + r2 = r1
(g1-g2) 0 0 0 g2 // G = (g1-g2)*1 + g2 = g1
(b1-b2) 0 0 0 b2 // B = (b1-b2)*1 + b2 = b1
0 0 0 1 0 // A = 1*A
例如,如果您希望输入图像的白色区域映射为青色 (r=0,g=1,b=1),而您的黑色输入区域映射为深紫色 (r=0.1, g= 0, b=0.2),你会使用像
这样的矩阵
/*R G B A 1 */
-0.1 0 0 0 0.1 // R = (-0.1)*R + 0.1
1 0 0 0 0 // G = 1*R + 0
0.8 0 0 0 0.2 // B = 0.8*R + 0.2
0 0 0 1 0 // A = 1*A
Using that matrix in a filter 应用于this original image。
请注意,这实际上与我在评论中链接的示例完全不同;在那个过滤器中,我试图将白色保持为白色,将黑色保持为黑色,但将灰色更改为彩色。为此,我使用了伽马校正滤镜,而不是颜色矩阵。