主な質問に答えるには、行列は条件のない変換にすぎないため、特定の色を置き換えるために行列を使用する方法はありません。
あなたの問題を解決するために:あなたが使用している組み合わせ(黒と白)のために、マトリックスを使用することができます!以下の詳細な回答を参照してください...
非常に良いリファレンス: カラー変換とカラーマトリックス。
マトリックスの推測に非常に近いですが、すべての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 |
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
対角線を通して、現在のRGBA値を1
維持しています。onを指定することで、その値を最大にすることもできます。1
[4][0]
黒と白を使用する特定のケースでは、白の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);
- 等
ご覧のとおり、赤のコンポーネントは常に最大に設定され、残りは維持されます。
サンプル画像:
左側にはアルファ値が指定された元の色が含まれ、右側には上記の変換が適用された同じ画像が含まれています。左側の円は次のように構成されています。
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);
}
}