C#:模拟gdi GetBitmapBits函数和GdiFlush,用位图填充字节数组

C#:模拟gdi GetBitmapBits函数和GdiFlush,用位图填充字节数组,c#,bitmap,bytearray,gdi,C#,Bitmap,Bytearray,Gdi,我创建了一个lib,其中我需要以正确的顺序填充307200个元素(320x240x4(=32位))的字节数组。对于位图,显示使用RGBA格式,我希望避免像现在这样使用interop来使用GetBitmapBits,而我更喜欢用c#代码来编写它,以了解字节是如何打印在上面的 有人能帮我吗 这是我的实际代码 /// <summary> /// LONG GetBitmapBits( /// __in HBITMAP hbmp, /// __

我创建了一个lib,其中我需要以正确的顺序填充307200个元素(320x240x4(=32位))的字节数组。对于位图,显示使用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(
///在HBITMAP hbmp中,
///_uuu在长缓冲区中,
///_u_uout LPVOID lpvBits
///  );
/// 
/// 
/// 
/// 
/// 
[DllImport(“Gdi32”,EntryPoint=“GetBitmapBits”)]
私有外部静态长GetBitmapBits([In]IntPtr hbmp,[In]int cbBuffer,[Out]byte[]lpvBits);
[DllImport(“Gdi32”,EntryPoint=“GdiFlush”)]
私有外部静态void GdiFlush();
私有void FillPixelArray(位图bmp,ref byte[]数组,bool bw=false)
{
彩色tmp;
如果(!bw)
{
IntPtr hbmp=bmp.GetHbitmap();
GdiFlush();
GetBitmapBits(hbmp,array.Length*Marshal.SizeOf(typeof(byte)),数组);
}
其他的
{
对于(int x=0;x
另一件事是,GetBitmapBits比我在C#中可以实现的任何实现都要快吗

另外,在
ref byte[]array
中不需要
ref
-array已经是一个引用类型,并且您没有在函数中修改
array
变量


p.p.S.
GetBitmapBits
返回
int
,而不是
long
(不要与
long
C宏混淆),
GdiFlush
返回
[return:MarshalAs(UnmanagedType.Bool)]Bool
,而不是
void
,从技术上讲,在Copy()调用中应该使用data.Stride而不是bmp.Width。是的,使用
步幅
是正确的,但在这种特殊情况下
步幅
将始终是
宽度*4
(因为
步幅
取整到4字节边界,我们使用ARGB-每像素4字节,甚至更多,我们的图像宽度是320=80*4)。还是换了代码。
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);