我正在使用这种语法:
<!-- just an example --> <filter id="colorMeMatrix"> <feColorMatrix in="SourceGraphic" type="matrix" values="0 0 0 0 0 1 1 1 1 0 0 0 0 0 0 0 0 0 1 0" />
解决方法
矩阵有五列四行.每行代表一个输出数字: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.
请注意,这实际上与我在评论中链接的示例完全不同;在那个过滤器中,我试图保持白色为白色,黑色为黑色,但将灰色改为颜色.为此,我使用了伽马校正滤镜,而不是颜色矩阵.