グレースケール画像を含むインスタンスがあるSystem.Drawing.Bitmap
場合、別の色の影響で「色付け」する組み込みの方法はありますか?
たとえば、コーヒー マグカップの白黒 (グレースケール) 画像があり、赤、緑、および紫のバージョンの個別の画像をプログラムで作成したいとします。
グレースケール画像を含むインスタンスがあるSystem.Drawing.Bitmap
場合、別の色の影響で「色付け」する組み込みの方法はありますか?
たとえば、コーヒー マグカップの白黒 (グレースケール) 画像があり、赤、緑、および紫のバージョンの個別の画像をプログラムで作成したいとします。
提供するコード例はありませんが、これを行う方法は次のとおりです。各ピクセルを RGB から HSV に変換し、各ピクセルの色相と彩度のコンポーネントを変更します。色相は色を制御します。値は同じままにする必要があります。結果は、明るさと暗さが同じで色が異なるビットマップになります。
編集:これが例です。色相と彩度の更新に注目してください。
public static Color ColorFromAhsb(int a, float h, float s, float b)
{
if (0 > a || 255 < a)
{
throw new Exception("a");
}
if (0f > h || 360f < h)
{
throw new Exception("h");
}
if (0f > s || 1f < s)
{
throw new Exception("s");
}
if (0f > b || 1f < b)
{
throw new Exception("b");
}
if (0 == s)
{
return Color.FromArgb(a, Convert.ToInt32(b * 255),
Convert.ToInt32(b * 255), Convert.ToInt32(b * 255));
}
float fMax, fMid, fMin;
int iSextant, iMax, iMid, iMin;
if (0.5 < b)
{
fMax = b - (b * s) + s;
fMin = b + (b * s) - s;
}
else
{
fMax = b + (b * s);
fMin = b - (b * s);
}
iSextant = (int)Math.Floor(h / 60f);
if (300f <= h)
{
h -= 360f;
}
h /= 60f;
h -= 2f * (float)Math.Floor(((iSextant + 1f) % 6f) / 2f);
if (0 == iSextant % 2)
{
fMid = h * (fMax - fMin) + fMin;
}
else
{
fMid = fMin - h * (fMax - fMin);
}
iMax = Convert.ToInt32(fMax * 255);
iMid = Convert.ToInt32(fMid * 255);
iMin = Convert.ToInt32(fMin * 255);
switch (iSextant)
{
case 1:
return Color.FromArgb(a, iMid, iMax, iMin);
case 2:
return Color.FromArgb(a, iMin, iMax, iMid);
case 3:
return Color.FromArgb(a, iMin, iMid, iMax);
case 4:
return Color.FromArgb(a, iMid, iMin, iMax);
case 5:
return Color.FromArgb(a, iMax, iMin, iMid);
default:
return Color.FromArgb(a, iMax, iMid, iMin);
}
}
private void Form1_Load(object sender, EventArgs e)
{
var bmp = new Bitmap("c:\\bw.bmp");
foreach (int y in Enumerable.Range(0, bmp.Height))
{
foreach (int x in Enumerable.Range(0,bmp.Width))
{
var p = bmp.GetPixel(x, y);
var h = p.GetHue();
var c = ColorFromAhsb(p.A, p.GetHue() + 200, p.GetSaturation() + 0.5f, p.GetBrightness());
bmp.SetPixel(x, y, c);
}
}
pictureBox1.Image = bmp;
//bmp.Dispose();
}
8 ビット イメージの場合は、別のパレット (Image.Palette) を使用できます。これは基本的に、考えられる各ピクセル バイト値に Color 値を割り当てるルックアップ テーブルです。ループ内のすべてのピクセルを変更するよりもはるかに高速です。
組み込みの方法はわかりませんが、各色をバイトではなくフロートとして表す場合 (255 は 1 - 完全な強度になります)、各チャネルに目的の色を掛けると、話している効果が得られます。
(1,1,1) "white" * (1,0,0) "red" = (1,0,0) "red"
(0.5,0.5, 0.5) "grey" * (0,1,0) "green" = (0,0.5,0) "dark green"
ただし、これをピクセルごとに適用する必要があります。
こちらをご覧ください
私は過去にこれを使用しました。あなたはToSepiaに特化して見たいと思っています。これを少し解体する必要があるかもしれませんが、私にとってはうまくいきました。
元の画像のコピーを作成し、上部の目的の色の別の半透明画像を配置します。
更新: http://www.codeproject.com/KB/cs/Merge_Images_in_C_.aspxの例を参照してください。