标题:【求助】 VB6 如何获取bitmap位图指针的二进制数据?麻烦大神帮忙解决一下
只看楼主
succeed318
Rank: 1
等 级:新手上路
帖 子:2
专家分:0
注 册:2020-3-24
结帖率:100%
已结贴  问题点数:20 回复次数:2 
【求助】 VB6 如何获取bitmap位图指针的二进制数据?麻烦大神帮忙解决一下
程序代码:
    Dim bmp As Long

    Dim G   As Long

    '从内存中创建一个bmp图像
    CreateBitmapWithGraphics bmp, G, 1013, 643
    
    ' 清除画布内容
    GdipGraphicsClear G, &HFFFFFFFF
    
    
    GdipLoadImageFromFile StrPtr(App.Path & "\1.jpg"), img
    GdipDrawImageRect G, img, ChangePiexlToMillter(4.5), ChangePiexlToMillter(14.5), 245, 307
    GdipCreateFontFamilyFromName StrPtr("宋体"), 0, fontfam
    GdipCreateStringFormat 0, 0, strformat
    GdipCreateSolidFill &HFF000000, brush
    GdipSetStringFormatAlign strformat, StringAlignmentNear
    GdipCreateFont fontfam, 8, FontStyle.FontStyleBold, UnitMillimeter, curFont
    GdipSetTextRenderingHint G, TextRenderingHintClearTypeGridFit
    rclayout.Left = ChangePiexlToMillter(37)
    rclayout.Top = ChangePiexlToMillter(14.5)
    '    rclayout.Right = 150   矩形的宽度width
    '    rclayout.Bottom = 150  矩形的高度height
    GdipDrawString G, StrPtr("李晓峰"), -1, curFont, rclayout, strformat, brush
    
    rclayout.Left = ChangePiexlToMillter(50)
    rclayout.Top = ChangePiexlToMillter(19)
    GdipDrawString G, StrPtr("621721 8888888888888"), -1, curFont, rclayout, strformat, brush
    
    rclayout.Left = ChangePiexlToMillter(50)
    rclayout.Top = ChangePiexlToMillter(24)
    GdipDrawString G, StrPtr("123456789123456789"), -1, curFont, rclayout, strformat, brush
    
    rclayout.Left = ChangePiexlToMillter(43)
    rclayout.Top = ChangePiexlToMillter(29)
    GdipDrawString G, StrPtr("2019年9月27日"), -1, curFont, rclayout, strformat, brush
    GdipRotateWorldTransform G, 180, MatrixOrderAppend
    
    '下面这句代码可以将bmp保存为一张图像。
    SaveImageToBMP bmp, "d:\test.bmp"

    '问题:现在想拿到bmp位图指针的byte数组信息,如何才能获取相应的位图二进制数组数据????


[此贴子已经被作者于2020-3-24 09:04编辑过]

搜索更多相关主题的帖子: Top 位图 Left bmp 二进制数 
2020-03-24 09:01
风吹过b
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:364
帖 子:4912
专家分:29900
注 册:2008-10-15
得分:14 

https://bbs.bccn.net/thread-481230-1-1.html 这里面,
有 解析内存BMP的函数。虽然与你的数据稍有差异,改改应该能用。

Public Sub AnalysisPB()


授人于鱼,不如授人于渔
早已停用QQ了
2020-03-24 09:43
succeed318
Rank: 1
等 级:新手上路
帖 子:2
专家分:0
注 册:2020-3-24
得分:0 
程序代码:
Option Explicit

'*********************************************************************************
'StdPicture、IStream、Byte() 互转
'作者:TZWSOHO
'
'参考了魏滔序的《VB6 结合 GDI+ 实现内存(Stream)压缩/解压缩 JPG 图像》
'http://blog.
'非常感谢魏滔序的代码!!!
'
'欢迎访问我的博客:http://blog.
'*********************************************************************************

' 第一步:(重要、重要、重要)首先在项目中引入'IStream.tlb'

Private Const GMEM_MOVEABLE                 As Long = &H2
Private Const ImageEncoderSuffix            As String = "-1A04-11D3-9A73-0000F81EF32E}"

'常量声明
Private Const ClsidJPEG                     As String = "{557CF401" & ImageEncoderSuffix
Private Const ClsidBMP                      As String = "{557CF400" & ImageEncoderSuffix
Private Const EncoderParameterValueTypeLong As Long = 4&
Private Const EncoderQuality                As String = "{1D5BE4B5-FA4A-452D-9CDD-5DB35105E7EB}"
Private Const GdiPlusVersion                As Long = 1&

'结构声明
Private Type GUID
    Data1 As Long
    Data2 As Integer
    Data3 As Integer
    Data4(0 To 7) As Byte
End Type

Private Type IID
    Data1 As Long
    Data2 As Integer
    Data3 As Integer
    Data4(0 To 7)  As Byte
End Type

Private Type PICTDESC
    cbSizeOfStruct As Long
    picType As Long
    hgdiObj As Long
    hPalOrXYExt As Long
End Type

Private Type EncoderParameter
    GUID As GUID
    NumberOfValues As Long
    Type As Long
    Value As Long
End Type

Private Type EncoderParameters
    Count As Long
    Parameter(15) As EncoderParameter
End Type

Private Type GDIPlusStartupInput
    GdiPlusVersion As Long
    DebugEventCallback As Long
    SuppressBackgroundThread As Long
    SuppressExternalCodecs As Long
End Type

Private Type GdiplusStartupOutput
    NotificationHook As Long
    NotificationUnhook As Long
End Type

'枚举声明
Private Enum Status
    OK = 0
    GenericError = 1
    InvalidParameter = 2
    OutOfMemory = 3
    ObjectBusy = 4
    InsufficientBuffer = 5
    NotImplemented = 6
    Win32Error = 7
    WrongState = 8
    Aborted = 9
    FileNotFound = 10
    ValueOverflow = 11
    AccessDenied = 12
    UnknownImageFormat = 13
    FontFamilyNotFound = 14
    FontStyleNotFound = 15
    NotTrueTypeFont = 16
    UnsupportedGdiplusVersion = 17
    GdiplusNotInitialized = 18
    PropertyNotFound = 19
    PropertyNotSupported = 20
    ProfileNotFound = 21
End Enum

'API声明
Private Declare Function GdipCreateBitmapFromHBITMAP _
                Lib "gdiplus" (ByVal hbm As Long, _
                               ByVal hpal As Long, _
                               ByRef bitmap As Long) As Status
Private Declare Function GdipCreateHBITMAPFromBitmap _
                Lib "gdiplus" (ByVal bitmap As Long, _
                               ByRef hbmReturn As Long, _
                               ByVal Background As Long) As Status
Private Declare Function GdipDisposeImage Lib "gdiplus" (ByVal image As Long) As Status
Private Declare Function GdipLoadImageFromStream _
                Lib "gdiplus" (ByVal Stream As IStream, _
                               ByRef image As Long) As Status
Private Declare Function GdiplusShutdown Lib "gdiplus" (ByVal token As Long) As Status
Private Declare Function GdiplusStartup _
                Lib "gdiplus" (ByRef token As Long, _
                               ByRef lpInput As GDIPlusStartupInput, _
                               ByRef lpOutput As GdiplusStartupOutput) As Status
Private Declare Function GdipSaveImageToStream _
                Lib "gdiplus" (ByVal image As Long, _
                               ByVal Stream As IStream, _
                               ByRef clsidEncoder As GUID, _
                               ByRef encoderParams As Any) As Status
Private Declare Function CLSIDFromString _
                Lib "ole32" (ByVal Str As Long, _
                             ByRef id As GUID) As Long
Private Declare Function CreateStreamOnHGlobal _
                Lib "ole32.dll" (ByRef hGlobal As Any, _
                                 ByVal fDeleteOnRelease As Long, _
                                 ByRef ppstm As Any) As Long
Private Declare Sub OleCreatePictureIndirect _
                Lib "oleaut32.dll" (ByRef lpPictDesc As PICTDESC, _
                                    ByRef riid As IID, _
                                    ByVal fOwn As Boolean, _
                                    ByRef lplpvObj As Object)

Private Declare Sub CopyMemory _
                Lib "kernel32.dll" _
                Alias "RtlMoveMemory" (ByRef Destination As Any, _
                                       ByRef Source As Any, _
                                       ByVal Length As Long)

Private Declare Function GlobalAlloc _
                Lib "kernel32.dll" (ByVal wFlags As Long, _
                                    ByVal dwBytes As Long) As Long
Private Declare Function GlobalLock Lib "kernel32.dll" (ByVal hMem As Long) As Long
'Private Declare Function GlobalSize Lib "kernel32.dll" (ByVal hMem As Long) As Long
Private Declare Function GlobalUnlock Lib "kernel32.dll" (ByVal hMem As Long) As Long
Private Declare Function GlobalFree Lib "kernel32.dll" (ByVal hMem As Long) As Long
'Private Declare Function GetHGlobalFromStream Lib "ole32.dll" (ByVal pstm As IStream, ByRef phglobal As Long) As Long

'By Modest
'根据版本初始化GDI+
Private Function StartUpGDIPlus(ByVal GdipVersion As Long) As Long
    Dim GdipToken         As Long
    Dim GdipStartupInput  As GDIPlusStartupInput
    Dim GdipStartupOutput As GdiplusStartupOutput
    GdipStartupInput.GdiPlusVersion = GdipVersion

    If GdiplusStartup(GdipToken, GdipStartupInput, GdipStartupOutput) = OK Then
        StartUpGDIPlus = GdipToken
    End If
End Function


'将位图指针转换为流再转为字节数组
Public Function BitmapToByteArray(ByVal bitmap As Long, _
                                  Optional ByVal JpegQuality As Long = 85) As Byte()
    Dim picStream    As IStream
    Dim lBitmap      As Long
    Dim tGUID        As GUID
    Dim bytBuff()    As Byte
    Dim tParams      As EncoderParameters
    Dim lngGdipToken As Long
   

    Dim hGlobal      As Long, lpBuffer As Long, dwSize As Long, Buff() As Byte
   

    lBitmap = bitmap
   

    lngGdipToken = StartUpGDIPlus(GdiPlusVersion)

    '检查JPG压缩比率
    If JpegQuality > 100 Then JpegQuality = 100
    If JpegQuality < 0 Then JpegQuality = 0

    Dim rc As RECTL
    GdipGetImageWidth bmp, rc.Right
    GdipGetImageHeight bmp, rc.Bottom

    '创建Bitmap
    hGlobal = GlobalAlloc(GMEM_MOVEABLE, rc.Bottom * rc.Right / 256) '创建缓冲区

    '创建Stream
    If CreateStreamOnHGlobal(ByVal hGlobal, False, picStream) = 0 Then

        '转换GUID,每种图片的tGUID不同。
        'If CLSIDFromString(StrPtr(ClsidJPEG), tGUID) = 0 Then
        If CLSIDFromString(StrPtr(ClsidBMP), tGUID) = 0 Then
            '设置JPG相关参数值
            tParams.Count = 1

            With tParams.Parameter(0)
                CLSIDFromString StrPtr(EncoderQuality), .GUID
                .NumberOfValues = 1
                .Type = EncoderParameterValueTypeLong
                .Value = VarPtr(JpegQuality)
            End With

            '将Bitmap数据保存到流(JPG格式)
            '            If GdipSaveImageToStream(lBitmap, picStream, tGUID, tParams) = OK Then
            If GdipSaveImageToStream(lBitmap, picStream, tGUID, ByVal 0) = OK Then
                'GetHGlobalFromStream picStream, hGlobal
                   

                picStream.Seek 0, STREAM_SEEK_CUR, dwSize '获取图像大小
                lpBuffer = GlobalLock(hGlobal) '获取缓冲区读写指针
                ReDim Buff(dwSize - 1): CopyMemory Buff(0), ByVal lpBuffer, dwSize '读取图像
                GlobalUnlock hGlobal: GlobalFree hGlobal '释放分配的缓冲区空间
                BitmapToByteArray = Buff
            End If
        End If
        Set picStream = Nothing
    End If
    GdipDisposeImage lBitmap
    GdiplusShutdown lngGdipToken
End Function

'By Modest
'从图像转换为流
Public Function PictureToStream(ByVal Picture As StdPicture, _
                                Optional ByVal JpegQuality As Long = 85) As IStream
    Dim picStream    As IStream
    Dim lBitmap      As Long
    Dim tGUID        As GUID
    Dim bytBuff()    As Byte
    Dim tParams      As EncoderParameters
    Dim lngGdipToken As Long
   

    lngGdipToken = StartUpGDIPlus(GdiPlusVersion)

    '检查JPG压缩比率
    If JpegQuality > 100 Then JpegQuality = 100
    If JpegQuality < 0 Then JpegQuality = 0

    '创建Bitmap
    If GdipCreateBitmapFromHBITMAP(Picture.Handle, 0, lBitmap) = OK Then

        '创建Stream
        If CreateStreamOnHGlobal(ByVal 0&, False, picStream) = 0 Then

            '转换GUID
            If CLSIDFromString(StrPtr(ClsidJPEG), tGUID) = 0 Then
                '设置JPG相关参数值
                tParams.Count = 1

                With tParams.Parameter(0)
                    CLSIDFromString StrPtr(EncoderQuality), .GUID
                    .NumberOfValues = 1
                    .Type = EncoderParameterValueTypeLong
                    .Value = VarPtr(JpegQuality)
                End With

                '将Bitmap数据保存到流(JPG格式)
                If GdipSaveImageToStream(lBitmap, picStream, tGUID, tParams) = OK Then
                    Set PictureToStream = picStream
                End If
            End If
            Set picStream = Nothing
        End If
    End If
    GdipDisposeImage lBitmap
    GdiplusShutdown lngGdipToken
End Function

'By Modest
'从流转换为图像
Public Function StreamToPicture(ByVal Stream As IStream) As StdPicture
    Dim picStream    As IStream
    Dim lBitmap      As Long
    Dim hBitmap      As Long
    Dim lngGdipToken As Long
    Dim tPictDesc    As PICTDESC
    Dim IID_IPicture As IID
    Dim oPicture     As IPicture

    lngGdipToken = StartUpGDIPlus(GdiPlusVersion)

    Set picStream = Stream
    '从Stream加载Bitmap
    If GdipLoadImageFromStream(picStream, lBitmap) = OK Then

        '根据Bitmap创建hBitbmp
        If GdipCreateHBITMAPFromBitmap(lBitmap, hBitmap, 0) = OK Then

            With tPictDesc
                .cbSizeOfStruct = Len(tPictDesc)
                .picType = vbPicTypeBitmap
                .hgdiObj = hBitmap
                .hPalOrXYExt = 0
            End With

            ' 初始化IPicture
            With IID_IPicture
                .Data1 = &H7BF80981
                .Data2 = &HBF32
                .Data3 = &H101A
                .Data4(0) = &H8B
                .Data4(1) = &HBB
                .Data4(3) = &HAA
                .Data4(5) = &H30
                .Data4(6) = &HC
                .Data4(7) = &HAB
            End With

            Call OleCreatePictureIndirect(tPictDesc, IID_IPicture, True, oPicture)
            Set StreamToPicture = oPicture
        End If
    End If

    Set picStream = Nothing
    GdipDisposeImage lBitmap
    GdiplusShutdown lngGdipToken
End Function

'By TZWSOHO
'从图像转换为流再转为字节数组
Public Function PictureToByteArray(ByVal Picture As StdPicture, _
                                   Optional ByVal JpegQuality As Long = 85) As Byte()
    Dim picStream    As IStream
    Dim lBitmap      As Long
    Dim tGUID        As GUID
    Dim bytBuff()    As Byte
    Dim tParams      As EncoderParameters
    Dim lngGdipToken As Long
   

    Dim hGlobal      As Long, lpBuffer As Long, dwSize As Long, Buff() As Byte
   

    lngGdipToken = StartUpGDIPlus(GdiPlusVersion)

    '检查JPG压缩比率
    If JpegQuality > 100 Then JpegQuality = 100
    If JpegQuality < 0 Then JpegQuality = 0

    '创建Bitmap
    If GdipCreateBitmapFromHBITMAP(Picture.Handle, 0, lBitmap) = OK Then
        hGlobal = GlobalAlloc(GMEM_MOVEABLE, Picture.Width * Picture.Height / 256) '创建缓冲区

        '创建Stream
        If CreateStreamOnHGlobal(ByVal hGlobal, False, picStream) = 0 Then

            '转换GUID
            If CLSIDFromString(StrPtr(ClsidJPEG), tGUID) = 0 Then
                '设置JPG相关参数值
                tParams.Count = 1

                With tParams.Parameter(0)
                    CLSIDFromString StrPtr(EncoderQuality), .GUID
                    .NumberOfValues = 1
                    .Type = EncoderParameterValueTypeLong
                    .Value = VarPtr(JpegQuality)
                End With

                '将Bitmap数据保存到流(JPG格式)
                If GdipSaveImageToStream(lBitmap, picStream, tGUID, tParams) = OK Then
                    'GetHGlobalFromStream picStream, hGlobal
                   

                    picStream.Seek 0, STREAM_SEEK_CUR, dwSize '获取图像大小
                    lpBuffer = GlobalLock(hGlobal) '获取缓冲区读写指针
                    ReDim Buff(dwSize - 1): CopyMemory Buff(0), ByVal lpBuffer, dwSize '读取图像
                    GlobalUnlock hGlobal: GlobalFree hGlobal '释放分配的缓冲区空间
                    PictureToByteArray = Buff
                End If
            End If
            Set picStream = Nothing
        End If
    End If
    GdipDisposeImage lBitmap
    GdiplusShutdown lngGdipToken
End Function

'By TZWSOHO
'从字节数组转换为流再转换为图像
Public Function ByteArrayToPicture(sBuf() As Byte) As StdPicture
    Dim picStream    As IStream
    Dim lBitmap      As Long
    Dim hBitmap      As Long
    Dim lngGdipToken As Long
    Dim tPictDesc    As PICTDESC
    Dim IID_IPicture As IID
    Dim oPicture     As IPicture
    Dim hGlobal      As Long, lpBuffer As Long
   

    lngGdipToken = StartUpGDIPlus(GdiPlusVersion)
   

    hGlobal = GlobalAlloc(GMEM_MOVEABLE, UBound(sBuf) + 1) '创建缓冲区
    lpBuffer = GlobalLock(hGlobal) '获取缓冲区读写指针
    CopyMemory ByVal lpBuffer, sBuf(0), UBound(sBuf) + 1 '复制字节数组内容到缓冲区

    '创建Stream
    If CreateStreamOnHGlobal(ByVal hGlobal, False, picStream) = 0 Then

        '从Stream加载Bitmap
        If GdipLoadImageFromStream(picStream, lBitmap) = OK Then

            '根据Bitmap创建hBitbmp
            If GdipCreateHBITMAPFromBitmap(lBitmap, hBitmap, 0) = OK Then

                With tPictDesc
                    .cbSizeOfStruct = Len(tPictDesc)
                    .picType = vbPicTypeBitmap
                    .hgdiObj = hBitmap
                    .hPalOrXYExt = 0
                End With
   

                ' 初始化IPicture
                With IID_IPicture
                    .Data1 = &H7BF80981
                    .Data2 = &HBF32
                    .Data3 = &H101A
                    .Data4(0) = &H8B
                    .Data4(1) = &HBB
                    .Data4(3) = &HAA
                    .Data4(5) = &H30
                    .Data4(6) = &HC
                    .Data4(7) = &HAB
                End With
   

                Call OleCreatePictureIndirect(tPictDesc, IID_IPicture, True, oPicture)
                Set ByteArrayToPicture = StreamToPicture(picStream)
            End If
        End If
        GlobalUnlock hGlobal: GlobalFree hGlobal '释放分配的缓冲区空间
        Set picStream = Nothing
    End If
    GdipDisposeImage lBitmap
    GdiplusShutdown lngGdipToken
End Function
2020-03-25 09:36



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-500542-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.052819 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved