ビットマップのピクセルを特定の色から新しい特定の色に再色付けする小さな関数があります。
私がコードで抱えている問題は次のとおりです。
1)この関数は、しきい値があるため考慮すべきではない白いピクセルを再マッピングする結果を提供します...(この計算を間違って定義していない限り)
2)特定の色が指定されている場合、たとえばLimeGreenの奇妙な結果が関数から返された画像に表示されます(これは、加算または減算の場合のバイトタイプのオーバーフローによるものと思われます)
私が使用しているベースイメージはここにあります:
http://www.freeimagehosting.net/uploads/c8745a9de1.png
私が得た結果はここで見つけることができます:
freeimagehosting.net/uploads/fa48e5a0eb.png(remapColorとしてColor.Magenta、newColorとしてColor.Redで呼び出され、白いピクセルが影響を受け、グラデーションの終わりが正しく色付けされていないようです)
freeimagehosting.net/uploads/8faec6a569.png(remapColorとしてColor.Magenta、newColorとしてColor.Yellowで呼び出され、白いピクセルが影響を受け、グラデーションの終わりが正しく色付けされていないようです)
freeimagehosting.net/uploads/2efd4c04aa.png(remapColorとしてColor.Magenta、newColorとしてColor.Blueで呼び出され、グラデーションが正しく色付けされていないようです)
freeimagehosting.net/uploads/defdf04e16.png(remapColorとしてColor.Magenta、newColorとしてColor.Tealで呼び出され、白いピクセルが影響を受け、グラデーションが正しく計算されていないようです)
このコードのために私が持っている関数は以下の通りです:提案ごとに更新されました
public unsafe static Bitmap RecolorImage(Bitmap original, Color remapColor, Color newColor)
{
Bitmap result = new Bitmap(original.Width, original.Height);
//lock the original bitmap in memory
BitmapData originalData = original.LockBits(
new Rectangle(0, 0, original.Width, original.Height),
ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
//lock the new bitmap in memory
BitmapData newData = result.LockBits(
new Rectangle(0, 0, original.Width, original.Height),
ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
//set the number of bytes per pixel
int pixelSize = 4;
int rthreshold = 128;
int gthreshold = 128;
int bthreshold = 128;
for (int y = 0; y < original.Height; y++)
{
//get the data from the original image
byte* oRow = (byte*)originalData.Scan0 + (y * originalData.Stride);
//get the data from the new image
byte* nRow = (byte*)newData.Scan0 + (y * newData.Stride);
for (int x = 0; x < original.Width; x++)
{
//examine the rgb values
byte r = (byte)((oRow[x * pixelSize]));
byte g = (byte)((oRow[x * pixelSize + 1]));
byte b = (byte)((oRow[x * pixelSize + 2]));
byte a = (byte)((oRow[x * pixelSize + 3]));
if (a > 0 &&
Math.Abs(remapColor.R - r) <= rthreshold &&
Math.Abs(remapColor.B - b) <= bthreshold &&
Math.Abs(remapColor.G - g) <= gthreshold
)
{
if (newColor.R == 0)
{
r = 0;
}
else
{
if (newColor.R > remapColor.R)
r = (byte)(r - newColor.R);
else
r = (byte)(r + newColor.R);
}
if (newColor.G == 0)
{
g = 0;
}
else
{
if (newColor.G > remapColor.G)
g = (byte)(g - newColor.G);
else
g = (byte)(g + newColor.G);
}
if (newColor.B == 0)
{
b = 0;
}
else
{
if (newColor.B > remapColor.B)
b = (byte)(b - newColor.B);
else
b = (byte)(b + newColor.B);
}
}
//set the new image's pixel remaped pixel color
nRow[x * pixelSize] = b; //B
nRow[x * pixelSize + 1] = g; //G
nRow[x * pixelSize + 2] = r; //R
nRow[x * pixelSize + 3] = a; //A
}
}
original.UnlockBits(originalData);
result.UnlockBits(newData);
return result;
}
何が...
私がやろうとしていることは可能ですか?
信頼できますか?
私のコードにバグがありますか?
グラデーションを使用してビットマップでこの「再マッピング可能な手法」を実現するためのより良い方法はありますか?
お時間をいただきありがとうございます。