我正在开发一个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
答案 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