BMP Tutor - Read *.bmp (file) --> hBMP (Get/Put)

Category: BMP Tutor Series (API)

Date: 03-28-2012

Return to Index


 
'Because the structure of bitmap file is well-defined, a programmer
'can read the file without using API.  Simple Get/Put statement are
'all that is required.
 
'The image color data can be read directly into a two-dimensional
'array, corresonding to the (x,y) positions of the image pixels.
 
'While in array form, the pixel color data can be modified by the
'application using customized code (there are no API to modify the
'color data within the array).
 
'Once changes are made to the image color data (the array), the
'two bitmap data structures and the image color data array can be
'written back to a file, again without the use of API.
 
'Specifically, a bitmap file (*.bmp) consists of the following structure:
1. BITMAPFILEHEADER   'data structure
2. BITMAPINFOHEADER   'data structure
4. ColorBytes         '3 bytes per pixel (with padding for Word alignment)
 
 
'Primary Code:
'This code revolves around using GET/PUT to read/write the two header
'structures (BITMAPFILEHEADER and BITMAPINFOHEADER), was well as to read/write
'the image color data into a Byte array.
 
   'Create Buffer array to hold image color data + padding bytes
   Dim Buffer(w*3+padding-1,h-1) As Byte     'pixel color array data (0-based array)
 
   'Open input file
   Open fSource For Binary as #1
   Get #1, , bmpheader                       'get BITMAPFILEHEADER
   Get #1, , bmpinfo                         'get BITMAPINFOHEADER
   Get #1, bmpheader.bfOffBits+1, Buffer()   'read image color data into Byte array
   Close #1
 
   'Open output file
   Open fTarget For Binary as #1
   Put #1,, bmpheader    'BITMAPFILEHEADER
   Put #1,, bmpinfo      'BITMAPINFOHEADER
   Put #1,, Buffer()     'write image color data (includes padding bytes)
   Close #1
 
 
 
'Compilable Example:
'GET is used to read the file header, info header, and image color data.
'PUT is used to return the headers/color data to a file. In this example
'the color data is edited and the changes written to a new bitmap file,
'all without displaying the image.
#Compiler PBWin 9, PBWin 10
#Compile EXE
#Dim All
#Include "Win32API.inc"
#Resource "gbsnippets.pbr"
 
Global hDlg, hGraphic, hBMP, DC_graphic, DC_BMP 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,"Read From File", 20,10,150,20
   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
      Local w,h As Long
      ReadEditSaveBitmapFile("cowgirl.bmp", "test.bmp", w, h)
      'display the results in a Graphic Control
      Control Add Graphic, hDlg, 900, "", 50,50,w,h
      Graphic Attach hDlg, 900 : Graphic Render "test.bmp", (0,0)-(w-1,h-1) :
   End If
End Function
 
Sub ReadEditSaveBitmapFile (fSource As String, fTarget As String, w As Long, h as Long)   'w,h are returned values
   Local bmpheader As BITMAPFILEHEADER, bmpinfo As BITMAPINFOHEADER, padding, x, y As Long
   'Open the file
   Open fSource For Binary as #1
   Get #1, , bmpheader    'get BITMAPFILEHEADER
   Get #1, , bmpinfo      'get BITMAPINFOHEADER
 
   'Optionally verify the file is of interest - Bitmap, 24bit, non-compressed
   If bmpheader.bfType <> CVI("BM") Then MsgBox ("bad file - ") + Mks$(bmpheader.bfType) : Exit Sub            'want bitmap file
   If bmpInfo.biCompression <> %BI_RGB Then MsgBox ("bad file - compressed") : Exit Sub    'want uncompressed
   If bmpInfo.biBitcount <> 24 Then MsgBox ("bad file - " + Str$(bmpInfo.biBitCount)) : Exit Sub              'want 24bit only
 
   'A two-dimension Byte array is used to hold the image color data + padding bytes
   w = bmpinfo.biWidth
   h = bmpinfo.biHeight
   padding  = (4 - (w*3) Mod 4) Mod 4
   Dim Buffer(w*3+padding-1,h-1) As Byte     'pixel color array data (0-based array)
 
   'read the buffer, which contains padded, upside-down, and BGR image color data
   Get #1, bmpheader.bfOffBits+1, Buffer()
   Close #1
 
   'Optional example of modifying the image color data within the Buffer() array
   For y = 0 to h-1                  'each row
      For x = 0 To w*3-1             '1 byte at a time, 1 pixel = 3 bytes, BGR byte order, ignores padding bytes
         If y <= (h-1)/2 Then Buffer(x,y) = 128  'top half darker RGB = 64,64,64 vs 128,128,128
      Next x
   Next y
 
   'Open output file
   Open fTarget For Binary as #1
   Put #1,, bmpheader    'BITMAPFILEHEADER
   Put #1,, bmpinfo      'BITMAPINFOHEADER
   Put #1,, Buffer()     'image data (size is paddesize)
   Close #1
End Sub
 
'gbs_00514
'Date: 03-10-2012


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