GetDIBBits does not fill the array corectly

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
 
M

Michael Phillips, Jr.

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)
 
A

active

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
 
M

Michael Phillips, Jr.

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.
 
A

active

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
 
M

Michael Phillips, Jr.

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.
 
A

active

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
 
A

active

just realize I hadn't changed to
Dim dibInfo As New Wnd.DIBSECTION

I do that now
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top