VB6:24位BMP → 32位ARGB处理 → 保存回24位BMP

张开发
2026/4/11 13:01:19 15 分钟阅读

分享文章

VB6:24位BMP → 32位ARGB处理 → 保存回24位BMP
VB624位BMP → 32位ARGB处理 → 保存回24位BMP整体思路读文件(24bit) → 解析Header → 升位到32bit数组 → [图像处理] → 压回24bit → 写文件完整代码1. 数据结构定义vb复制 模块顶部声明 Option Explicit BMP 文件头 (14字节) Private Type BITMAPFILEHEADER bfType As Integer BM H4D42 bfSize As Long bfReserved1 As Integer bfReserved2 As Integer bfOffBits As Long 像素数据偏移 End Type DIB 信息头 (40字节) Private Type BITMAPINFOHEADER biSize As Long biWidth As Long biHeight As Long 负数从上到下正数从下到上 biPlanes As Integer biBitCount As Integer biCompression As Long biSizeImage As Long biXPelsPerMeter As Long biYPelsPerMeter As Long biClrUsed As Long biClrImportant As Long End Type 32位像素结构方便按字段访问 Private Type PIXEL32 B As Byte G As Byte R As Byte A As Byte AlphaBMP通常填0处理时可当255用 End Type2. 读取24位BMP → 升位为32位Long数组vb复制 返回值32位像素数组(一维行优先)以及宽高 pixels32(0 to W*H-1) 每个元素 H00RRGGBB 格式的Long Public Function Load24BitBMP(filePath As String, _ ByRef W As Long, ByRef H As Long, _ ByRef pixels32() As Long) As Boolean Dim fh As BITMAPFILEHEADER Dim bih As BITMAPINFOHEADER Dim f As Integer On Error GoTo ErrHandler f FreeFile Open filePath For Binary Access Read As #f --- 读文件头 --- Get #f, , fh If fh.bfType H4D42 Then 不是BMP Close #f: Exit Function End If --- 读信息头 --- Get #f, , bih If bih.biBitCount 24 Then 必须是24位 Close #f: Exit Function End If W bih.biWidth H Abs(bih.biHeight) Dim topDown As Boolean topDown (bih.biHeight 0) 负高度 从上到下存储 --- 读原始24位像素字节 --- 每行需要4字节对齐 Dim stride24 As Long stride24 ((W * 3 3) \ 4) * 4 Dim rawSize As Long rawSize stride24 * H Dim raw() As Byte ReDim raw(rawSize - 1) Get #f, fh.bfOffBits 1, raw 1 因为VB6文件位置从1开始 Close #f --- 升位BGR 24bit → ARGB 32bit --- ReDim pixels32(W * H - 1) Dim x As Long, y As Long Dim srcRow As Long 源数据中实际的行考虑Y翻转 Dim srcOff As Long Dim dstOff As Long Dim r As Byte, g As Byte, b As Byte For y 0 To H - 1 BMP默认从下到上存储翻转y If topDown Then srcRow y Else srcRow (H - 1) - y ← Y轴翻转在这里处理 End If srcOff srcRow * stride24 dstOff y * W For x 0 To W - 1 b raw(srcOff x * 3) BGR顺序 g raw(srcOff x * 3 1) r raw(srcOff x * 3 2) 打包成 H00RRGGBB (Alpha0可按需改为255) pixels32(dstOff x) _ CLng(r) * H10000 CLng(g) * H100 CLng(b) Next x Next y Load24BitBMP True Exit Function ErrHandler: If f 0 Then Close #f Load24BitBMP False End Function3. 32位数组 → 保存为24位BMPvb复制Public Function Save24BitBMP(filePath As String, _ pixels32() As Long, _ W As Long, H As Long) As Boolean Dim fh As BITMAPFILEHEADER Dim bih As BITMAPINFOHEADER Dim f As Integer On Error GoTo ErrHandler --- 计算尺寸 --- Dim stride24 As Long stride24 ((W * 3 3) \ 4) * 4 行对齐到4字节 Dim pixelDataSize As Long pixelDataSize stride24 * H --- 填写文件头 --- fh.bfType H4D42 BM fh.bfOffBits 14 40 文件头 信息头 fh.bfSize fh.bfOffBits pixelDataSize fh.bfReserved1 0 fh.bfReserved2 0 --- 填写信息头 --- bih.biSize 40 bih.biWidth W bih.biHeight H 正数 从下到上标准BMP bih.biPlanes 1 bih.biBitCount 24 bih.biCompression 0 BI_RGB 无压缩 bih.biSizeImage pixelDataSize bih.biXPelsPerMeter 0 bih.biYPelsPerMeter 0 bih.biClrUsed 0 bih.biClrImportant 0 --- 构建像素字节数组32bit → 24bit BGR同时Y翻转--- Dim raw() As Byte ReDim raw(pixelDataSize - 1) Dim x As Long, y As Long Dim srcOff As Long, dstOff As Long Dim px As Long Dim r As Byte, g As Byte, b As Byte For y 0 To H - 1 保存时要翻转回来从下到上 Dim dstRow As Long dstRow (H - 1) - y srcOff y * W dstOff dstRow * stride24 For x 0 To W - 1 px pixels32(srcOff x) 从 H00RRGGBB 拆出各通道 b CByte(px And HFF) g CByte((px \ H100) And HFF) r CByte((px \ H10000) And HFF) 写入BGR顺序 raw(dstOff x * 3) b raw(dstOff x * 3 1) g raw(dstOff x * 3 2) r Next x 行末填充字节已自动为0ReDim默认 Next y --- 写文件 --- f FreeFile Open filePath For Binary Access Write As #f Put #f, , fh Put #f, , bih Put #f, , raw Close #f Save24BitBMP True Exit Function ErrHandler: If f 0 Then Close #f Save24BitBMP False End Function4. 调用示例vb复制Sub TestBMPProcess() Dim pixels() As Long Dim W As Long, H As Long 读入 → 升为32位 If Not Load24BitBMP(C:\test\input.bmp, W, H, pixels) Then MsgBox 读取失败 Exit Sub End If 在这里做你的图像处理 例如反色 Dim i As Long For i 0 To W * H - 1 Dim px As Long: px pixels(i) Dim r As Byte: r CByte((px \ H10000) And HFF) Dim g As Byte: g CByte((px \ H100) And HFF) Dim b As Byte: b CByte(px And HFF) pixels(i) CLng(255 - r) * H10000 _ CLng(255 - g) * H100 _ CLng(255 - b) Next i 保存回24位BMP If Save24BitBMP(C:\test\output.bmp, pixels, W, H) Then MsgBox 保存成功尺寸 W x H End If End Sub关键点总结问题处理方式Y轴方向读取时翻转保存时翻转回来字节顺序文件是BGR内存数组用RRGGBB行对齐stride ((W*33)\4)*432位格式Long R*H10000 G*H100 BAlpha通道填0即可处理时可视为255性能提示如果需要进一步提速可以用CopyMemoryRtlMoveMemory配合Long指针直接操作内存避免逐字节循环速度可提升10倍以上。需要的话可以继续展开这部分。

更多文章