Date: 02-16-2022
Return to Index
created by gbSnippets
'This snippet covers covers creating/editing/saving a DIB Section, which is
'one of the three types of bitmaps supported by the GDI API:
'DDB - cannot be saved, can be drawn on using API
'DIB - can be saved, cannot be drawn on by using API (cannot be selected into a DC)
'DIBSection - can be saved, can be drawn on by using API
'The combined ability to be saved and to be selected into a device context
'makes a DIB Section a very useful graphic object.
'DIB Section Data Structures
'A DIB Section is defined by a single BITMAPINFO data structure, which in turn
'contains only two elements - a BITMAPINFOHEADER and an array of RGBQuad variables.
Local bm As BitmapInfo
Type BITMAPINFO
bmiHeader AS BITMAPINFOHEADER 'BITMAPINFOHEADER data structure
bmiColors As Long 'array of RGBQuad data structures
End Type
'Defining a DIB Section is exactly like defining a DIB, except that the
'DIB Section does NOT have a BITMAPFILEHEADER that would be used to create
'a *.bmp file.
'Here's the BITMAPINFOHEADER and comments on each member:
Type BITMAPINFOHEADER
biSize As DWord 'size of this structure (40 bytes)
biWidth As Long 'image width - pixel width of image (does not include padding bytes)
biHeight As Long 'image height - pixel height of image (- for bottoms up image)
biPlanes As Word 'bit planes - always 1
biBitCount As Word 'resolution (24 or 32 bits per pixel for this tutorial)
biCompression As DWord 'compression method (%BI_RGB for uncompressed)
biSizeImage AS DWord '0 for %BI_RGB compression
biXPelsPerMeter As Long 'not used by CreateDIBSection
biYPelsPerMeter As Long 'not used by CreateDIBSection
biClrUsed AS DWord 'no palette with 24/32bit bitmaps, so set to zero
biClrImportant AS DWord 'no palette with 24/32bit bitmaps, so set to zero
End Type
'And here's the Type definition of an RGBQUAD:
Type RGBQUAD
rgbBlue As Byte
rgbGreen As Byte
rgbRed As Byte
rgbReserved As Byte
End Type
'Because the image color data is contained in an RGBQUAD array, the bytes are always
'aligned on a Long boundary - a requirement of bitmap image color data bytes. No padding
'bytes are required.
'CreateDIBSection API
'This API creates a DIB that applications can write to directly. It's arguments are:
CreateDIBSection hDc, pbmi, iUsage, ppvBits, hSection, dwOffset
hdc 'device context
pbmi 'pointer to a BITMAPINFO structure
iUsage 'type of data in bmiColors of BITMAPINFO. DIB_RGB_COLORS for array of RGB values
ppvBits 'pointer to variable that receives a pointer to the location of the DIB Bit values.
hSection 'if %Null, system allocates memory for the DIB
dwOffset 'ignored if hSection is %NULL
'If successful, function returns handle to DIB and ppvBits points to the bitmap bit values.
'Primary Code:
'These are the API typically used when working with a DIB Section.
CreateCompatibleDC
CreateDIBSection
GetDIBits
SetDIBits
SelectObject
DeleteObject
DeleteDC
BitBlt
'Compilable Example: (Jose Includes)
#Compiler PBWin 9, PBWin 10
#Compile EXE
#Dim All
%Unicode=1
#Debug Error On 'catch array/pointer errors - OFF in production
#Debug Display On 'display untrapped errors - OFF in production
#Include "Win32API.inc"
Global hDlg, hGraphic, DC_Graphic as DWord
Function PBMain() As Long
Dialog New Pixels, 0, "Test Code",300,300,200,200, %WS_OverlappedWindow To hDlg
Control Add Button, hDlg, 100,"Push", 50,10,100,20
Control Add Image, hDlg, 200,"", 50,40,100,100, %WS_Border
Control Handle hDlg, 200 To hGraphic
DC_graphic = GetDC (hGraphic) 'DC for Image control
Dialog Show Modal hDlg Call DlgProc
End Function
CallBack Function DlgProc() As Long
If CB.Msg = %WM_Command AND CB.Ctl = 100 AND CB.Ctlmsg = %BN_Clicked Then
CreateDisplayDIBSection (100,100, "test.bmp")
End If
End Function
Sub CreateDisplayDIBSection(w As Long, h as Long, fName as String)
'Create device context (where the DIB Section will be selected)
Local hMemDC As DWord
hMemDC = CreateCompatibleDC(%NULL)
'Create/fill in the BITMAPINFO data structure
Local BI As BITMAPINFO
BI.bmiHeader.biSize = 40 'SizeOf(BI.bmiHeader) = 40
BI.bmiHeader.biWidth = w
BI.bmiHeader.biHeight = h
BI.bmiHeader.biPlanes = 1
BI.bmiHeader.biBitCount = 32 'must be 32 because an RGBQuad is 32 bytes
BI.bmiHeader.biCompression = %BI_RGB '%BI_RGB = 0
BI.bmiHeader.biSizeImage = 0 'zero for %BI_RGB images
BI.bmiHeader.biXPelsPerMeter = 0 'zero (device-specific value)
BI.bmiHeader.biYPelsPerMeter = 0 'zero (device-specific value)
BI.bmiHeader.biClrUsed = 0 'no palette so set to zero
BI.bmiHeader.biClrImportant = 0 'zero means all colors are important
'Create the DIB Section and select it into the DC
Local hDIBSection As DWord, P as DWord
hDIBSection = CreateDIBSection(hMemDC, BI, %DIB_RGB_COLORS, VarPTR(P), 0, 0)
'Create the RGBQuad color data and pre-load all colors to red (for grins)
Dim Colors(w-1,h-1) As RGBQUAD
Local x, y As Long
For x = 0 to w-1 : For y = 0 to h-1 : Colors(x,y).rgbRed = 128 : Next : Next
CopyMemory(ByVal P, ByVal VarPTR(Colors(0)), w*h*4) 'Dest, Source, #Bytes
'Now that the DIB Section is in a device context, you can use API to draw on it
SelectObject(hMemDC, hDIBSection)
Ellipse hMemDC, 20,20,60,60
'If desired, you can get the info back into your array, make changes, and put changes into the DIBSection
CopyMemory(ByVal VarPTR(Colors(0)), ByVal P, w*h*4) 'Dest, Source, #Bytes
For x = w/2 to w-1 : For y = h/2 to h-1 : Colors(x,y).rgbRed = 64 : Next : Next
CopyMemory(ByVal P, ByVal VarPTR(Colors(0)), w*h*4) 'Dest, Source, #Bytes
'Copy the completed drawing (hMEMDC) to the graphics control
BitBlt(DC_Graphic, 0, 0, w, h, hMemDC, 0, 0, %SRCCOPY)
End Sub
'gbs_00522
'Date: 03-10-2012
http://www.garybeene.com/sw/gbsnippets.htm