VBA手动创建BMP

时间:2013-03-04 21:49:55

标签: vba access-vba bmp

我正在开发一个VBA类来创建QR码,我在将QR数据位写入实际BMP文件时感到困惑。为了获得BMP结构和代码,我可以尝试使用下面的代码制作一个21 x 21像素的全白色位图。这几乎可以工作,除了每行中最左边的列是黄色而不是白色。关于可能发生什么的任何想法?我猜我的标题定义有问题,但我不确定。我远非BMP的专业人士。我的代码基于我在http://answers.microsoft.com/en-us/office/forum/office_2007-customize/how-can-i-create-a-bitmap-image-with-vba/4976480a-d20b-4b2a-8ecc-436428d9586b

找到的内容
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

'==================================================

Public Sub makeBMP(intQR() As Integer)
    Dim bmpFile As typBITMAPFILE
    Dim lngRowSize As Long
    Dim lngPixelArraySize As Long
    Dim lngFileSize As Long
    Dim j, k, l, x As Integer

    Dim bytRed, bytGreen, bytBlue As Integer
    Dim lngRGBColoer() As Long

    Dim strBMP As String

    With bmpFile
        With .bmfh
            .strType = "BM"
            .lngSize = 0
            .intRes1 = 0
            .intRes2 = 0
            .lngOffset = 54
        End With
        With .bmfi
            .lngSize = 40
            .lngWidth = 21
            .lngHeight = 21
            .intPlanes = 1
            .intBits = 24
            .lngCompression = 0
            .lngImageSize = 0
            .lngxResolution = 0
            .lngyResolution = 0
            .lngColorCount = 0
            .lngImportantColors = 0
        End With
        lngRowSize = Round(.bmfi.intBits * .bmfi.lngWidth / 32) * 4
        lngPixelArraySize = lngRowSize * .bmfi.lngHeight

        ReDim .bmbits(lngPixelArraySize)
        ReDim lngRGBColor(21, 21)
        For j = 1 To 21  ' For each row, starting at the bottom and working up...
            'each column starting at the left
            For x = 1 To 21
                k = k + 1
                .bmbits(k) = 255
                k = k + 1
                .bmbits(k) = 255
                k = k + 1
                .bmbits(k) = 255
            Next x

            If (21 * .bmfi.intBits / 8 < lngRowSize) Then   ' Add padding if required
                For l = 21 * .bmfi.intBits / 8 + 1 To lngRowSize
                    k = k + 1
                    .bmbits(k) = 0
                Next l
            End If
        Next j
        .bmfh.lngSize = 14 + 40 + lngPixelArraySize
     End With ' Defining bmpFile

    strBMP = "C:\Desktop\Sample.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

4 个答案:

答案 0 :(得分:3)

这是一个行字节对齐问题。用一个额外的字节填充每一行,你的问题应该消失。

发布,以便您有一个检查答案。 :)

此外,这是一个很好的bmp工具。 https://50ab6472f92ea10153000096.openlearningapps.net/run/view

答案 1 :(得分:2)

此BMP导出代码中存在一个小错误

的行
lngRowSize = Round(.bmfi.intBits * .bmfi.lngWidth / 32) * 4

实际上应该说

'old line:    lngRowSize = Round(.bmfi.intBits * .bmfi.lngWidth / 32) * 4
 lngRowSize = WorksheetFunction.Ceiling_Precise(.bmfi.intBits * .bmfi.lngWidth / 32) * 4

之前,圆函数阻止了某些图像宽度正确导出,并且代码引发了错误。以前拒绝的宽度:(3,6,7,11,14,15,19,22,23,27,30,...)

我假设你不再需要这个代码,但是我从这里复制了它,我也想到了其他人。

答案 2 :(得分:1)

我运行了你的代码以验证黄线。仔细观察后,我相信可以通过设置bmpfile.bmpbits字节数组的边界来解决问题。当您定义数组时,您将下限保留为空,因此默认情况下数组将从0开始。如果您像这样重新调暗数组

    ReDim .bmbits(1 To lngPixelArraySize)

你会得到一个纯白色的样本.bmp。我跑来验证它对我有用。

祝你好运。我可以看到让k从-1开始会起作用。剩下的唯一问题是你的数组大小将有一个额外的字节。

答案 3 :(得分:0)

制作&#34;天花板&#34;功能正常(VBA / excel 2007)&#34;精确&#34;声明不是必需的。
Macro正常工作:

lngRowSize = WorksheetFunction.Ceiling(.bmfi.intBits * .bmfi.lngWidth / 32, 0.5) * 4