回答您的主要问题:没有方法可以使用矩阵替换特定颜色,因为矩阵只是 转换无条件。
解决您的问题:因为您使用的是组合(黑白),所以可以使用矩阵!请参阅下面的详细答案...
一个很好的参考: Color Transformations and the Color Matrix.
您的矩阵猜测非常接近,但是,您并没有保持所有 RGBA 值不变。看这里:
R G B A W
___________________
| 1 | 0 | 0 | 0 | 0 |
| 0 | 1 | 0 | 0 | 0 |
| 0 | 0 | 1 | 0 | 0 |
| 0 | 0 | 0 | 1 | 0 |
| 1 | 0 | 0 | 0 | 1 |
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
通过对角线1,您正在保持当前的 RGBA 值。通过在 [4][0] 上指定 1,您也表示您希望 的值达到最大值!
在您使用黑白的特定情况下,只替换黑色会起作用,因为白色的 RGB 值已经达到最大值(255、255、255)。
因此,通过上述矩阵,您基本上是在说:将所有 RGB 保持在当前值,但我还希望红色始终为 255!
使用序列(R、G、B、A)并应用上述规则的详细示例:最大红色 = 255,其他一切都相同。
- 找到 (0, 0, 0, 128) = 结果 (255, 0, 0, 128);
- 找到 (0, 0, 0, 192) = 结果 (255, 0, 0, 192);
- 找到 (255, 255, 255, 128) = 结果 (255, 255, 255, 128);
- 找到 (255, 255, 255, 255) = 结果 (255, 255, 255, 255);
- 等
如您所见,红色组件始终设置为最大值,其余部分保持不变。
示例图片:
左侧包含指定了 alpha 值的原始颜色,而右侧包含应用了上述转换的相同图像。左侧的圆圈按以下方式组织:
R G B A | R G B A
______________________|_______________________
circle[0,0] = | (255, 0, 0, 0) | (255, 0, 0, 64) | = circle[0,1]
[1,0] = | ( 0, 0, 0, 0) | ( 0, 0, 0, 64) | = [1,1]
[2,0] = | (255, 255, 255, 0) | (255, 255, 255, 64) | = [2,1]
[3,0] = | (255, 0, 0, 128) | (255, 0, 0, 255) | = [3,1]
[4,0] = | ( 0, 0, 0, 128) | ( 0, 0, 0, 255) | = [4,1]
[5,0] = | (255, 255, 255, 128) | (255, 255, 255, 255) | = [5,1]
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
生成示例图像的C#代码:
using (Bitmap myBitmap = new Bitmap(102, 302))
{
Graphics g = Graphics.FromImage(myBitmap);
g.Clear(Color.Transparent);
g.FillEllipse(new SolidBrush(Color.FromArgb(0, Color.Red)), new Rectangle(1, 1, 50, 50));
g.FillEllipse(new SolidBrush(Color.FromArgb(0, Color.Black)), new Rectangle(1, 51, 50, 50));
g.FillEllipse(new SolidBrush(Color.FromArgb(0, Color.White)), new Rectangle(1, 101, 50, 50));
g.FillEllipse(new SolidBrush(Color.FromArgb(64, Color.Red)), new Rectangle(51, 1, 50, 50));
g.FillEllipse(new SolidBrush(Color.FromArgb(64, Color.Black)), new Rectangle(51, 51, 50, 50));
g.FillEllipse(new SolidBrush(Color.FromArgb(64, Color.White)), new Rectangle(51, 101, 50, 50));
g.FillEllipse(new SolidBrush(Color.FromArgb(128, Color.Red)), new Rectangle(1, 151, 50, 50));
g.FillEllipse(new SolidBrush(Color.FromArgb(128, Color.Black)), new Rectangle(1, 201, 50, 50));
g.FillEllipse(new SolidBrush(Color.FromArgb(128, Color.White)), new Rectangle(1, 251, 50, 50));
g.FillEllipse(new SolidBrush(Color.FromArgb(255, Color.Red)), new Rectangle(51, 151, 50, 50));
g.FillEllipse(new SolidBrush(Color.FromArgb(255, Color.Black)), new Rectangle(51, 201, 50, 50));
g.FillEllipse(new SolidBrush(Color.FromArgb(255, Color.White)), new Rectangle(51, 251, 50, 50));
g.DrawRectangle(Pens.Black, 0, 0, myBitmap.Width - 1, myBitmap.Height - 1);
e.Graphics.DrawImage(myBitmap, 0, 0);
ColorMatrix colorMatrix = new ColorMatrix(
new Single[][]
{
new [] { 1f, 0, 0, 0, 0 },
new [] { 0f, 1, 0, 0, 0 },
new [] { 0f, 0, 1, 0, 0 },
new [] { 0f, 0, 0, 1, 0 },
new [] { 1f, 0, 0, 0, 1 }
});
using (ImageAttributes imageAttr = new ImageAttributes())
{
imageAttr.SetColorMatrix(colorMatrix);
Rectangle rect = new Rectangle(150, 0, myBitmap.Width, myBitmap.Height);
e.Graphics.DrawImage(myBitmap, rect, 0, 0, myBitmap.Width, myBitmap.Height, GraphicsUnit.Pixel, imageAttr);
}
}