我创建了一个lib,我需要在正确的顺序中为位图填充307200个元素的字节数组(320x240x4(= 32bit)),显示器使用格式RGBA,我会就像我现在正在做的那样避免使用interop来使用GetBitmapBits,而我更喜欢用c#代码编写它以了解字节的打印方式。
有人可以帮助我吗?
这是我的实际代码
/// <summary>
/// LONG GetBitmapBits(
/// __in HBITMAP hbmp,
/// __in LONG cbBuffer,
/// __out LPVOID lpvBits
/// );
/// </summary>
/// <param name="hbmp"></param>
/// <param name="cbBuffer"></param>
/// <param name="lpvBits"></param>
/// <returns></returns>
[DllImport("Gdi32", EntryPoint = "GetBitmapBits")]
private extern static long GetBitmapBits([In] IntPtr hbmp, [In] int cbBuffer, [Out] byte[] lpvBits);
[DllImport("Gdi32", EntryPoint = "GdiFlush")]
private extern static void GdiFlush();
private void FillPixelArray(Bitmap bmp, ref byte[] array, bool bw = false)
{
Color tmp;
if (!bw)
{
IntPtr hbmp = bmp.GetHbitmap();
GdiFlush();
GetBitmapBits(hbmp, array.Length * Marshal.SizeOf(typeof(byte)), array);
}
else
{
for (int x = 0; x < LgLcd.NativeConstants.LGLCD_BMP_WIDTH; ++x)
{
for (int y = 0; y < LgLcd.NativeConstants.LGLCD_BMP_HEIGHT; ++y)
{
tmp = bmp.GetPixel(x, y);
array[y * 160 + x] = (byte)((tmp.R == 255 && tmp.G == 255 && tmp.B == 255) ? 0 : 255);
}
}
}
}
另一件事,GetBitmapBits比我在C#中可以做的任何实现更快吗?
答案 0 :(得分:2)
var data = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height),
System.Drawing.Imaging.ImageLockMode.ReadOnly,
System.Drawing.Imaging.PixelFormat.Format32bppArgb);
Marshal.Copy(data.Scan0, array, 0, data.Stride * data.Height);
bmp.UnlockBits(data);
P.S。 ref
中不需要ref byte[] array
- 数组已经是引用类型,并且您没有在函数中修改array
变量。
P.P.S。 GetBitmapBits
返回int
,而不是long
(不要与LONG
C宏混淆),GdiFlush
返回[return:MarshalAs(UnmanagedType.Bool)] bool
,而不是void
}。