指摘されているように、この問題の最も難しい部分は、特定の色が黒、白、または赤に「近い」かどうかを知ることです。私はあなたのために働くかもしれない何かを一緒に投げました:
Color GetNearestOfBWR(Color c)
{
float redness = Math.Abs(180 - c.GetHue()) / 180;
float brightness = c.GetBrightness();
float saturation = c.GetSaturation();
それぞれ 0 から 1 の間の 3 つの値があり、0 から 1 に増加すると、赤に近づくことを意味します (大まかに言えば、赤を増やす/緑と青を減らす、色を増やす/黒を減らす、色を増やす/灰色を減らす)。
どの時点で色が「赤」を構成するかを決定する必要があり、正直なところ、それは判断の呼びかけです. あなたは単に持つことができます
double brightColourfulRedness = Math.Sqrt(
redness*redness + brightness*brightness + saturation*saturation);
if (brightColourfulRedness > 1)
return Color.FromArgb(255, 0, 0); // red;
(単純なユークリッド ノルム) しかし、特定のプロパティを別のプロパティよりも強く重み付けしたり、単に1
しきい値を変更したりしたい場合があります。
次に、何を黒または白にマップするかを決定する必要があります。これは次のように簡単です
if (brightness > 0.5)
return Color.FromArgb(255, 255, 255); // white
return Color.FromArgb(0, 0, 0); // black
}
すごい!これで、好みに応じて色を赤、白、または黒にマッピングする関数ができました。あとは、ビットマップの各ピクセルに適用するだけです。ファイルからロードした を上書きしてBitmap
も問題ない場合は、配列は必要ありません。あなたはただ行うことができます:
int height = imageoriginal.Height;
int width = imageoriginal.Width;
for (int i = 0; i < width; i++)
{
for (int j = 0; j < height; j++)
{
Color origC = imageoriginal.GetPixel(i, j);
Color newC = GetNearestOfBWR(origC);
imageoriginal.SetPixel(i, j, newC);
}
}
これは非常に遅くなる可能性があるため、代わりに DmitryG のLockBits
コードを使用することもできますが、提供される と が必要とする の間で変換する必要がありint
ます。(そしてこれを行う、と私は信じています。)Color
GetNearestOfBWR
FromArgb
ToArgb