GetDIBBits does not fill the array corectly

  • Thread starter Thread starter active
  • Start date Start date
A

active

I have another post asking how to fill in the structure but I now think
GetDIBBits is the way, I just can't get it to work!

I can make the following run but GetDIBBits does not fill the array to
correctly reflect the data from the bitmap.

Any helpful suggestions would be appreciated.

Dim hInBitmap As IntPtr = InBitmap.GetHbitmap()

'Dim hInBitmapDC As IntPtr = GetDC(hInBitmap)

Dim hInBitmapDC As IntPtr = GetDC(Nothing)

Dim dibInfo As New BitmapInfo

Dim dibInfoPtr As IntPtr = Marshal.AllocHGlobal(Marshal.SizeOf(dibInfo))

If GetDIBits(hInBitmapDC, hInBitmap, 0, 0, Nothing, dibInfoPtr,
DIB_RGB_COLORS) = 0 Then

DeleteObject(hInBitmap)

Exit Sub

End If

dibInfo = CType(Marshal.PtrToStructure(dibInfoPtr, dibInfo.GetType),
BitmapInfo)



Marshal.FreeHGlobal(dibInfoPtr)

ReleaseDC(hInBitmap, hInBitmapDC)

Above: Don't know which GetDC is correct?



Public Declare Auto Function GetDIBits Lib "gdi32" (ByVal hDC As IntPtr,
ByVal hBitmap As IntPtr, ByVal nStartScan As Integer, ByVal nNumScans As
Integer, ByRef lpBits As Byte, ByRef lpBI As IntPtr, ByVal wUsage As
Integer) As Integer

Above: Do not know how to use lpBI As BitmapInfo - would that be better?



Below: Don't know how to set the array size at run time when I know how many
colors there are?

Public Structure BitmapInfo

Public bmiHeader As BitmapInfoHeader

<MarshalAs(UnmanagedType.ByValArray, SizeConst:=256)> Public bmiColors() As
RGBQuad

End Structure

Public Structure BitmapInfoHeader

Public biSize As Integer

Public biWidth As Integer

Public biHeight As Integer

Public biPlanes As Short

Public biBitCount As Short

Public biCompression As Integer

Public biSizeImage As Integer

Public biXPelsPerMeter As Integer

Public biYPelsPerMeter As Integer

Public biClrUsed As Integer

Public biClrImportant As Integer

End Structure

Public Structure RGBQuad

Public rgbBlue As Byte

Public rgbGreen As Byte

Public rgbRed As Byte

Public rgbReserved As Byte

End Structure
 
In order to use GetDIBits you should use a memory device context not the
desktop's display context.

You also need to allocate memory for the number of scanlines that you wish
to retrieve.

You can pass a managed memory array of bytes where the number of allocated
bytes is equal to bmi.bmiHeader.biSizeImage.

IntPtr hdc = GetDC(IntPtr.Zero)
IntPtr hdcMem = CreateCompatibleDC(hdc)
int nScanlinesRetrieved = GetDIBits(hdcMem, hBitmap, 0, nScanlines, pBits,
bmi, DIB_RGB_COLORS)
nScanlines can be 1 to Height of your bitmap

Don't forget to free gdi resources(i.e, device contexts)
 
Am I going about this correctly.

All I'm trying to do is to fill in a BitmapInfo structure to use with
CreateDIBSection

If I get an array of Bytes can I pass that to CreateDIBSection some how

thanks again
 
If I get an array of Bytes can I pass that to CreateDIBSection some how

You use GetDIBits to retieve a bitmap's bits out of an existing GDI DIB.

You use it the same way you would use Lockbits to retrieve the bits out of
an existing System.Drawing.Bitmap.
 
I thought I read that if lpBits is NULL it fills in lpBi.

lpvBits
[out] Pointer to a buffer to receive the bitmap data. If this parameter is
NULL, the function passes the dimensions and format of the bitmap to the
BITMAPINFO structure pointed to by the lpbi parameter.


What is the simplest way to get the BitmapInfo info out of a Bitmap?

Thanks
 
I thought I read that if lpBits is NULL it fills in lpBi.

It only fills the BITMAPINFOHEADER. You must read 1 scanline for it to
work.
What is the simplest way to get the BitmapInfo info out of a Bitmap?

Using GetObject with DIBSECTION is the best way to get this information.

Use GetDIBColorTable to get the color table, if any.

Use GetDIBits to get the bits.

active said:
I thought I read that if lpBits is NULL it fills in lpBi.

lpvBits
[out] Pointer to a buffer to receive the bitmap data. If this parameter is
NULL, the function passes the dimensions and format of the bitmap to the
BITMAPINFO structure pointed to by the lpbi parameter.


What is the simplest way to get the BitmapInfo info out of a Bitmap?

Thanks


Michael Phillips said:
You use GetDIBits to retieve a bitmap's bits out of an existing GDI DIB.

You use it the same way you would use Lockbits to retrieve the bits out
of an existing System.Drawing.Bitmap.
 
Using GetObject with DIBSECTION is the best way to get this information.
Dim hInBitmap As IntPtr = InBitmap.GetHbitmap()

Dim dibInfo As New BitmapInfo

Dim dibInfoPtr As IntPtr = Marshal.AllocHGlobal(Marshal.SizeOf(dibInfo))

If GetObject(hInBitmap, Marshal.SizeOf(dibInfo), dibInfoPtr) <>
Marshal.SizeOf(dibInfo) Then

DeleteObject(hInBitmap)

Exit Sub

End If



I'm back to square one.

That's the first thing I tried.

Can't get past it returning zero for a 256 8bpp bitmap



Public Declare Auto Function GetObject Lib "gdi32.dll" (ByVal hObject As
IntPtr, ByVal nCount As Integer, ByVal nEntries As IntPtr) As Integer


Public Structure BitmapInfo

Public bmiHeader As BitmapInfoHeader

<MarshalAs(UnmanagedType.ByValArray, SizeConst:=256)> Public bmiColors() As
RGBQuad

End Structure

Public Structure BitmapInfoHeader

Public biSize As Integer

Public biWidth As Integer

Public biHeight As Integer

Public biPlanes As Short

Public biBitCount As Short

Public biCompression As Integer

Public biSizeImage As Integer

Public biXPelsPerMeter As Integer

Public biYPelsPerMeter As Integer

Public biClrUsed As Integer

Public biClrImportant As Integer

End Structure
 
Back
Top