Generate a bitmap file (.BMP) from Excel


Option Explicit
Option Base 1

Private Type typHEADER
    strType As String * 2  ' Signature of file = "BM"
    lngSize As Long        ' File size
    intRes1 As Integer     ' reserved = 0
    intRes2 As Integer     ' reserved = 0
    lngOffset As Long      ' offset to the bitmap data (bits)
End Type

Private Type typINFOHEADER
    lngSize As Long        ' Size
    lngWidth As Long       ' Height
    lngHeight As Long      ' Length
    intPlanes As Integer   ' Number of image planes in file
    intBits As Integer     ' Number of bits per pixel
    lngCompression As Long ' Compression type (set to zero)
    lngImageSize As Long   ' Image size (bytes, set to zero)
    lngxResolution As Long ' Device resolution (set to zero)
    lngyResolution As Long ' Device resolution (set to zero)
    lngColorCount As Long  ' Number of colors (set to zero for 24 bits)
    lngImportantColors As Long ' "Important" colors (set to zero)
End Type

Private Type typPIXEL
    bytB As Byte    ' Blue
    bytG As Byte    ' Green
    bytR As Byte    ' Red
End Type

Private Type typBITMAPFILE
    bmfh As typHEADER
    bmfi As typINFOHEADER
    bmbits() As Byte
End Type
'
' This is a routine to test the "subCellsToBMP" macro.
'
Sub subTestBMP()
    Dim shtBMP As String
    Dim rngBMP As Range
'
    shtBMP = "BMP Cells"
    Set rngBMP = ThisWorkbook.Worksheets(shtBMP).Range("A1:AN11")
'
    Call subCellsToBMP(rngBMP)
End Sub
'
' This macro will take an input range of cells
' from an Excel worksheet and create a BMP file
' that reflects the colors in the cells.  The
' BMP file is 24 bit, uncompressed.
'
Sub subCellsToBMP(rngPicture As Range)
    Dim i As Long, j As Long, k As Long, l As Long
'
    Dim bmpFile As typBITMAPFILE
    Dim lngRowSize As Long
    Dim lngPixelArraySize As Long
    Dim lngFileSize As Long
'
    Dim bytRed As Integer, bytGreen As Integer, bytBlue As Integer
    Dim lngRGBColor() As Long
'
    Dim strBMP As String
'
' First check for a valid range - set some reasonable limits
'
    If (rngPicture Is Nothing) Then Exit Sub
    If (rngPicture.Cells.Count #LT 4) Then
        MsgBox "Tried to export a BMP with less than 4 pixels!", vbOKOnly + vbCritical, "BMP Export Error"
        Exit Sub
    End If
'
' Create the BMP data structures based on the selected cells.
'
    With bmpFile
' BMP Header
        With .bmfh
            .strType = "BM"      ' Basic BMP file
            .lngSize = 0         ' Determine later (total file size in bytes)
            .intRes1 = 0         ' Set to zero
            .intRes2 = 0         ' Set to zero
            .lngOffset = 54       ' Location where the bitmap data start
        End With
' DIB Header
        With .bmfi
            .lngSize = 40        ' This will be a Version 3 BMP
            .lngWidth = rngPicture.Columns.Count ' Number of pixels wide
            .lngHeight = rngPicture.Rows.Count   ' Number of pixels high
            .intPlanes = 1       ' Set to one
            .intBits = 24        ' 24 bits per pixel (RGB)
            .lngCompression = 0  ' No compression
            .lngImageSize = 0    ' Can be set to zero
            .lngxResolution = 0  ' Set to zero
            .lngyResolution = 0  ' Set to zero
            .lngColorCount = 0   ' Set to zero (no color pallette)
            .lngImportantColors = 0 ' Set to zero
        End With
' Bitmap pixel array (ensure 32 bit boundary alignment!)
        lngRowSize = Round(.bmfi.intBits * .bmfi.lngWidth / 32) * 4
        lngPixelArraySize = lngRowSize * .bmfi.lngHeight
'
        ReDim .bmbits(lngPixelArraySize) ' Total number of bytes to store padded pixel array
'
' Read color data from cells (no color is considered white)
' Start from bottom row and work up.  Pad each row to an even
' 4 byte boundary if required.
' NOTE: Instead of reading colors, you can read numbers and get the "bytBlue", "bytGreen",
'       and "bytRed" values directly from those numbers.
'
        k = 0
        ReDim lngRGBColor(rngPicture.Rows.Count, rngPicture.Columns.Count)
        For j = rngPicture.Rows.Count To 1 Step -1 ' rngPicture.Column To rngPicture.Column + rngPicture.Columns.Count - 1
            For i = 1 To rngPicture.Columns.Count ' rngPicture.Row + rngPicture.Rows.Count - 1 To rngPicture.Row Step -1
                If (LongToRGB(rngPicture.Cells(j, i).Interior.Color, bytRed, bytGreen, bytBlue)) Then
                    k = k + 1
                    .bmbits(k) = bytBlue
                    k = k + 1
                    .bmbits(k) = bytGreen
                    k = k + 1
                    .bmbits(k) = bytRed
                Else
                    k = k + 1
                    .bmbits(k) = 255
                    k = k + 1
                    .bmbits(k) = 255
                    k = k + 1
                    .bmbits(k) = 255
                End If
            Next i ' For each column...
            If (rngPicture.Columns.Count * .bmfi.intBits / 8 #LT lngRowSize) Then   ' Add padding if required
                For l = rngPicture.Columns.Count * .bmfi.intBits / 8 + 1 To lngRowSize
                    k = k + 1
                    .bmbits(k) = 0
                Next l
            End If
        Next j ' For each row, starting at the bottom and working up...
'
' The structures have all been loaded.  Calculate file size
' and then dump the data to a file.
'
        .bmfh.lngSize = 14 + 40 + lngPixelArraySize
'
    End With ' Defining bmpFile
'
    strBMP = ThisWorkbook.Path & "\" & "Sample5.BMP"
'
    Open strBMP For Binary Access Write As 1 Len = 1
'
    Put 1, 1, bmpFile.bmfh
    Put 1, , bmpFile.bmfi
    Put 1, , bmpFile.bmbits
'
    Close
'
End Sub
'
' Convert a long integer representation of a color to its
' red, green, blue values.
'
Public Function LongToRGB(theColor As Long, iRed As Integer, iGreen As Integer, iBlue As Integer) As Boolean
'
    Dim lColor As Long
    lColor = theColor      'work long
    iRed = lColor Mod 256  'get red component
    iGreen = (lColor \ 256) Mod 256 'get green component
    iBlue = (lColor \ 256 \ 256) Mod 256 'get blue component
'
    LongToRGB = True
End Function


Sub sb10x10px()
    Cells.Select
    Selection.RowHeight = 7.5
    Selection.ColumnWidth = 0.83
    Range("A1").Select
End Sub

Sub sb12x10px()
    Cells.Select
    Selection.RowHeight = 36.75
    Selection.ColumnWidth = 6.43
    Range("A1").Select
End Sub

Sub sb96x80px() ' x8
    Cells.Select
    Selection.RowHeight = 4.5
    Selection.ColumnWidth = 0.5
    Range("A1").Select
End Sub

'
' This is a routine to test the "subCellsToBMP" macro.
'
Sub subTestBMP()
    Dim shtBMP As String
    Dim rngBMP As Range
'
    shtBMP = "BMP Cells"
    shtBMP = "Sheet1"
    'Set rngBMP = ThisWorkbook.Worksheets(shtBMP).Range("A1:EB55")
    'Set rngBMP = ThisWorkbook.Worksheets(shtBMP).Range("A1:AZ54")
    'Set rngBMP = ThisWorkbook.Worksheets(shtBMP).Range("A1:M10")
    'Set rngBMP = ThisWorkbook.Worksheets(shtBMP).Range("A1:DH80")
    Set rngBMP = ThisWorkbook.Worksheets(shtBMP).Range("M1:DH80")
'
    Call subCellsToBMP(rngBMP)
End Sub





Tags - Microsoft Excel VBA 2007, bitmap, file type .BMP http://bit.ly/xlBMP