一部のコードをBitmap.GetPixelからLockBitsによって返される直接ピクセルバッファーを使用するように変更しているときに問題が発生しました。LockBitsによって返されたデータは、GetPixelと比較して異なるColor値を提供しているようです。
この変更により異なる色が生成され、自動化された単体テストが機能しなくなるため、これは残念なことです。Format32bppArgbをビットマップにロードする29*30ピクセルのpngファイルがあります。これは、LockBitsとGetPixelによって返されるデータが異なるということでしょうか。どうすればこれを回避できますか?
ロードされたビットマップでそれを再現するためのいくつかのコードがあります
public unsafe static Bitmap Convert(Bitmap originalBitmap)
{
Bitmap converted = new Bitmap(originalBitmap);
Rectangle rect = new Rectangle(0, 0, converted.Width, converted.Height);
var locked = converted.LockBits(rect, ImageLockMode.ReadWrite, originalBitmap.PixelFormat);
byte* pData = (byte*)locked.Scan0;
// bytes per pixel
var bpp = ((int)converted.PixelFormat >> 11) & 31;
byte* r;
byte* g;
byte* b;
byte* a;
for (int y = 0; y < locked.Height; y++)
{
var row = pData + (y * locked.Stride);
for (int x = 0; x < locked.Width; x++)
{
a = row + x * bpp + 3;
r = row + x * bpp + 2;
g = row + x * bpp + 1;
b = row + x * bpp + 0;
var col = Color.FromArgb(*a, *r, *g, *b);
var origCol = originalBitmap.GetPixel(x, y);
if (origCol != col)
{
Debug.Print("Orig: {0} Pixel {1}", origCol, col);
}
}
}
converted.UnlockBits(locked);
return converted;
}
Orig: Color [A=128, R=128, G=128, B=255] Pixel Color [A=128, R=127, G=127, B=255]
Orig: Color [A=0, R=128, G=128, B=255] Pixel Color [A=0, R=0, G=0, B=0]
Orig: Color [A=45, R=128, G=128, B=255] Pixel Color [A=45, R=130, G=130, B=254]
ok -2 -2 +1
ほとんどの場合ですが、丸めと変換が行われているようです。GetPixelによって返されるのと同じようにLockBitsにデータを返すように強制できますか?