我似乎无法将我的大脑包裹在图像周围并将它们从byte[]
原始RGB颜色转换为BitMap
。我找到了一个解决方案,允许我使用byte[]
将RGB 24bpp BitMap
转换为SetPixel
,但我已经读过使用LockBits
要快得多,所以我正在尝试弄清楚如何这样做。
使用SetPixel
方法,我使用以下方式获取反转图像:
public static Bitmap CreateBitmap24bppRgb(byte[] bmpData, int width, int height)
{
var bmp = new Bitmap(width, height, PixelFormat.Format24bppRgb);
var pos = 0;
for (var y = 0; y < height; y++)
{
for (var x = 0; x < width; x++)
{
bmp.SetPixel(x, y, Color.FromArgb(bmpData[pos], bmpData[pos + 1], bmpData[pos + 2]));
pos += 3;
}
}
return bmp;
}
我似乎无法弄清楚如何反转。但是当我尝试使用LockBits
时,图像只是黑色,我不确定我做错了什么,看起来很简单。
public static Bitmap CreateBitmap24bppRgb(byte[] data, int width, int height)
{
var bmp = new Bitmap(width, height, PixelFormat.Format24bppRgb);
//Create a BitmapData and Lock all pixels to be written
var bmpData = bmp.LockBits(
new Rectangle(0, 0, bmp.Width, bmp.Height),
ImageLockMode.WriteOnly, bmp.PixelFormat);
//Copy the data from the byte array into BitmapData.Scan0
for (int y = 0; y < bmp.Height - 1; y++)
{
Marshal.Copy(data, y * bmp.Width, bmpData.Scan0 bmpData.Stride);
}
//Unlock the pixels
bmp.UnlockBits(bmpData);
return bmp;
}
我只是好奇这里出了什么问题?
答案 0 :(得分:4)
如果您要创建新位图,而不是修改现有位图,则没有理由使用LockBits
或Marshal.Copy
。
选择the Bitmap
constructor that takes a pointer to pixel data。
public static Bitmap CreateBitmap24bppRgb(byte[] data, int width, int height)
{
GCHandle pin = GCHandle.Alloc(data, GCHandleType.Pinned);
var bmp = new Bitmap(width, height,
(width * 3 + 3) / 4 * 4,
PixelFormat.Format24bppRgb,
Marshal.UnsafeAddrOfPinnedArrayElement(data, 0));
bmp = (Bitmap)bmp.Clone(); // workaround the requirement that the memory address stay valid
// the clone step can also crop and/or change PixelFormat, if desired
GCHandle.Free(pin);
return bmp;
}
(或使用unsafe
块,pinned
关键字和指针