what is the problem with this GetDIBits invoke?
-
i want to invoke GetDIBits function ,this is my code: ----------------------------------------- public struct BITMAPINFOHEADER { public uint biSize; // DWORD public long biWidth; // LONG public long biHeight; //LONG public uint biPlanes; // WORD public uint biBitCount; // WORD public uint biCompression; // DWORD public uint biSizeImage; // DWORD public long biXPelsPerMeter; // LONG public long biYPelsPerMeter; // LONG public uint biClrUsed; // DWORD public uint biClrImportant; // DWORD } public struct RGBQUAD { public byte rgbBlue; public byte rgbGreen; public byte rgbRed; public byte rgbReserved; } public struct BITMAPINFO { public BITMAPINFOHEADER bmiHeader; public RGBQUAD bmiColors; // } code above is the structure definition; [DllImport("gdi32.dll")] public static extern int GetDIBits(IntPtr hdc, IntPtr hbmp, uint uStartScan,uint cScanLines, out byte[] lpvBits, ref BITMAPINFO lpbmi, uint uUsage); ---------------------------------------------------- BITMAPINFO bmi = new BITMAPINFO(); bmi.bmiHeader.biSize = 60; bmi.bmiHeader.biBitCount = 0; IntPtr hScreenDC = CreateDC("DISPLAY",null,null,IntPtr.Zero); IntPtr hMemDC = CreateCompatibleDC(hScreenDC); IntPtr hBitmap = CreateCompatibleBitmap(hScreenDC,800,600); byte[] lpvBits = null; int mResult = GetDIBits(hMemDC,hBitmap,0,1,out lpvBits,ref bmi,0); if( mResult != 0) MessageBox.Show("Success"); else MessageBox.Show("Failure"); -------------------------------- the code above is to invoke GetDIBits().The MSDN says if lpvBits is null, bmi should be filled with DC and bitmap Info and mResult should return Non-Zero. However the mResult is always Zero. How to solve this problem?
-
i want to invoke GetDIBits function ,this is my code: ----------------------------------------- public struct BITMAPINFOHEADER { public uint biSize; // DWORD public long biWidth; // LONG public long biHeight; //LONG public uint biPlanes; // WORD public uint biBitCount; // WORD public uint biCompression; // DWORD public uint biSizeImage; // DWORD public long biXPelsPerMeter; // LONG public long biYPelsPerMeter; // LONG public uint biClrUsed; // DWORD public uint biClrImportant; // DWORD } public struct RGBQUAD { public byte rgbBlue; public byte rgbGreen; public byte rgbRed; public byte rgbReserved; } public struct BITMAPINFO { public BITMAPINFOHEADER bmiHeader; public RGBQUAD bmiColors; // } code above is the structure definition; [DllImport("gdi32.dll")] public static extern int GetDIBits(IntPtr hdc, IntPtr hbmp, uint uStartScan,uint cScanLines, out byte[] lpvBits, ref BITMAPINFO lpbmi, uint uUsage); ---------------------------------------------------- BITMAPINFO bmi = new BITMAPINFO(); bmi.bmiHeader.biSize = 60; bmi.bmiHeader.biBitCount = 0; IntPtr hScreenDC = CreateDC("DISPLAY",null,null,IntPtr.Zero); IntPtr hMemDC = CreateCompatibleDC(hScreenDC); IntPtr hBitmap = CreateCompatibleBitmap(hScreenDC,800,600); byte[] lpvBits = null; int mResult = GetDIBits(hMemDC,hBitmap,0,1,out lpvBits,ref bmi,0); if( mResult != 0) MessageBox.Show("Success"); else MessageBox.Show("Failure"); -------------------------------- the code above is to invoke GetDIBits().The MSDN says if lpvBits is null, bmi should be filled with DC and bitmap Info and mResult should return Non-Zero. However the mResult is always Zero. How to solve this problem?
I dunno, but I do recall having no success with this function. Create a DIBSection instead, or better yet, just create a Bitmap and forget all this DLLImport stuff. Why do you need it ? Christian I have drunk the cool-aid and found it wan and bitter. - Chris Maunder
-
i want to invoke GetDIBits function ,this is my code: ----------------------------------------- public struct BITMAPINFOHEADER { public uint biSize; // DWORD public long biWidth; // LONG public long biHeight; //LONG public uint biPlanes; // WORD public uint biBitCount; // WORD public uint biCompression; // DWORD public uint biSizeImage; // DWORD public long biXPelsPerMeter; // LONG public long biYPelsPerMeter; // LONG public uint biClrUsed; // DWORD public uint biClrImportant; // DWORD } public struct RGBQUAD { public byte rgbBlue; public byte rgbGreen; public byte rgbRed; public byte rgbReserved; } public struct BITMAPINFO { public BITMAPINFOHEADER bmiHeader; public RGBQUAD bmiColors; // } code above is the structure definition; [DllImport("gdi32.dll")] public static extern int GetDIBits(IntPtr hdc, IntPtr hbmp, uint uStartScan,uint cScanLines, out byte[] lpvBits, ref BITMAPINFO lpbmi, uint uUsage); ---------------------------------------------------- BITMAPINFO bmi = new BITMAPINFO(); bmi.bmiHeader.biSize = 60; bmi.bmiHeader.biBitCount = 0; IntPtr hScreenDC = CreateDC("DISPLAY",null,null,IntPtr.Zero); IntPtr hMemDC = CreateCompatibleDC(hScreenDC); IntPtr hBitmap = CreateCompatibleBitmap(hScreenDC,800,600); byte[] lpvBits = null; int mResult = GetDIBits(hMemDC,hBitmap,0,1,out lpvBits,ref bmi,0); if( mResult != 0) MessageBox.Show("Success"); else MessageBox.Show("Failure"); -------------------------------- the code above is to invoke GetDIBits().The MSDN says if lpvBits is null, bmi should be filled with DC and bitmap Info and mResult should return Non-Zero. However the mResult is always Zero. How to solve this problem?
Try declaring your structs like below or even better use a managed equivalent of GetDIBits, which is Bitmap.LockBits
IntPtr hBitmap = CreateCompatibleBitmap(hScreen, 800, 600); Bitmap bitmap = Bitmap.FromHbitmap(hBitmap); BitmapData bData = bitmap.LockBits(new Rectangle(0,0,bitmap.Width,bitmap.Height), ImageLockMode.ReadWrite, bitmap.PixelFormat);
or as I said above try to declare your structs like this if you absolutely must stick to GetDIBits
[StructLayout(LayoutKind.Sequential)] public class BITMAPINFOHEADER { public uint biSize; // DWORD public long biWidth; // LONG public long biHeight; //LONG public uint biPlanes; // WORD public uint biBitCount; // WORD public uint biCompression; // DWORD public uint biSizeImage; // DWORD public long biXPelsPerMeter; // LONG public long biYPelsPerMeter; // LONG public uint biClrUsed; // DWORD public uint biClrImportant; // DWORD public BITMAPINFOHEADER() { biSize = Marshal.SizeOf(this); } } [StructLayout(LayoutKind.Sequential)] public class RGBQUAD { public byte rgbBlue; public byte rgbGreen; public byte rgbRed; public byte rgbReserved; } [StructLayout(LayoutKind.Sequential)] public class BITMAPINFO { public BITMAPINFOHEADER bmiHeader; public RGBQUAD [] bmiColors; public BITMAPINFO() { bmiHeader = new BITMAPINFOHEADER(); bmiColors = new RGBQUAD[1]; } }
-
i want to invoke GetDIBits function ,this is my code: ----------------------------------------- public struct BITMAPINFOHEADER { public uint biSize; // DWORD public long biWidth; // LONG public long biHeight; //LONG public uint biPlanes; // WORD public uint biBitCount; // WORD public uint biCompression; // DWORD public uint biSizeImage; // DWORD public long biXPelsPerMeter; // LONG public long biYPelsPerMeter; // LONG public uint biClrUsed; // DWORD public uint biClrImportant; // DWORD } public struct RGBQUAD { public byte rgbBlue; public byte rgbGreen; public byte rgbRed; public byte rgbReserved; } public struct BITMAPINFO { public BITMAPINFOHEADER bmiHeader; public RGBQUAD bmiColors; // } code above is the structure definition; [DllImport("gdi32.dll")] public static extern int GetDIBits(IntPtr hdc, IntPtr hbmp, uint uStartScan,uint cScanLines, out byte[] lpvBits, ref BITMAPINFO lpbmi, uint uUsage); ---------------------------------------------------- BITMAPINFO bmi = new BITMAPINFO(); bmi.bmiHeader.biSize = 60; bmi.bmiHeader.biBitCount = 0; IntPtr hScreenDC = CreateDC("DISPLAY",null,null,IntPtr.Zero); IntPtr hMemDC = CreateCompatibleDC(hScreenDC); IntPtr hBitmap = CreateCompatibleBitmap(hScreenDC,800,600); byte[] lpvBits = null; int mResult = GetDIBits(hMemDC,hBitmap,0,1,out lpvBits,ref bmi,0); if( mResult != 0) MessageBox.Show("Success"); else MessageBox.Show("Failure"); -------------------------------- the code above is to invoke GetDIBits().The MSDN says if lpvBits is null, bmi should be filled with DC and bitmap Info and mResult should return Non-Zero. However the mResult is always Zero. How to solve this problem?
thanks for your suggestions. i choose GetDIBits function for i need to get bits info from hBitmap or hDC and to transfer them on the net. i think transfer bits quicker than this way: get image first and convert into bits,then to send. but i do have a subsequent problem : the size may be too large.
-
thanks for your suggestions. i choose GetDIBits function for i need to get bits info from hBitmap or hDC and to transfer them on the net. i think transfer bits quicker than this way: get image first and convert into bits,then to send. but i do have a subsequent problem : the size may be too large.
You realize there's much easier ways that don't require unmanaged functions? If you're using a
TcpClient
or some other connection, just get theNetworkStream
and write yourBitmap
to the stream. Simple. If you want to convert it first (a waste of time), then use either write to a memory stream and then send the bytes, or use theImageConverter
like so:ImageConverter converter = TypeDescriptor.GetConverter(typeof(Image));
byte[] buffer = (byte[])converter.ConvertTo(image, typeof(byte[]));You really should read the class library documentation in the .NET Framework SDK. There are plenty of ways to do this using only managed code, and a heck of a lot easier as well. Even if you wanted to get the DIB bits, just use
Bitmap.LockBits
as someone else mentioned. There is absolutely no reason to P/Invoke unmanaged functions.Microsoft MVP, Visual C# My Articles
-
You realize there's much easier ways that don't require unmanaged functions? If you're using a
TcpClient
or some other connection, just get theNetworkStream
and write yourBitmap
to the stream. Simple. If you want to convert it first (a waste of time), then use either write to a memory stream and then send the bytes, or use theImageConverter
like so:ImageConverter converter = TypeDescriptor.GetConverter(typeof(Image));
byte[] buffer = (byte[])converter.ConvertTo(image, typeof(byte[]));You really should read the class library documentation in the .NET Framework SDK. There are plenty of ways to do this using only managed code, and a heck of a lot easier as well. Even if you wanted to get the DIB bits, just use
Bitmap.LockBits
as someone else mentioned. There is absolutely no reason to P/Invoke unmanaged functions.Microsoft MVP, Visual C# My Articles