BMP Tutor - Manually Create --> hDIB

Category: BMP Tutor Series (API)

Date: 02-16-2022

Return to Index


 
'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


created by gbSnippets
http://www.garybeene.com/sw/gbsnippets.htm