• GDI+_SavePic


      1 Option Explicit
      2  
      3 Private Const UnitPixel                  As Long = 2
      4 Private Const EncoderQuality             As String = "{1D5BE4B5-FA4A-452D-9CDD-5DB35105E7EB}"
      5  
      6 Private Type GdiplusStartupInput
      7     GdiplusVersion           As Long
      8     DebugEventCallback       As Long
      9     SuppressBackgroundThread As Long
     10     SuppressExternalCodecs   As Long
     11 End Type
     12  
     13 Private Enum EncoderParameterValueType
     14     EncoderParameterValueTypeByte = 1
     15     EncoderParameterValueTypeASCII = 2
     16     EncoderParameterValueTypeShort = 3
     17     EncoderParameterValueTypeLong = 4
     18     EncoderParameterValueTypeRational = 5
     19     EncoderParameterValueTypeLongRange = 6
     20     EncoderParameterValueTypeUndefined = 7
     21     EncoderParameterValueTypeRationalRange = 8
     22 End Enum
     23  
     24 Private Type EncoderParameter
     25     GUID(0 To 3)        As Long
     26     NumberOfValues      As Long
     27     Type                As EncoderParameterValueType
     28     Value               As Long
     29 End Type
     30  
     31 Private Type EncoderParameters
     32     Count               As Long
     33     Parameter           As EncoderParameter
     34 End Type
     35  
     36 Private Type ImageCodecInfo
     37     ClassID(0 To 3)     As Long
     38     FormatID(0 To 3)    As Long
     39     CodecName           As Long
     40     DllName             As Long
     41     FormatDescription   As Long
     42     FilenameExtension   As Long
     43     MimeType            As Long
     44     Flags               As Long
     45     Version             As Long
     46     SigCount            As Long
     47     SigSize             As Long
     48     SigPattern          As Long
     49     SigMask             As Long
     50 End Type
     51  
     52 Private Declare Function GdiplusStartup Lib "gdiplus" (Token As Long, inputbuf As GdiplusStartupInput, Optional ByVal outputbuf As Long = 0) As Long
     53 Private Declare Sub GdiplusShutdown Lib "gdiplus" (ByVal Token As Long)
     54 Private Declare Function GdipSaveImageToFile Lib "gdiplus" (ByVal hImage As Long, ByVal sFilename As Long, clsidEncoder As Any, encoderParams As Any) As Long
     55 Private Declare Function GdipDisposeImage Lib "gdiplus" (ByVal Image As Long) As Long
     56 Private Declare Function GdipCreateBitmapFromHBITMAP Lib "gdiplus" (ByVal hbm As Long, ByVal hPal As Long, Bitmap As Long) As Long
     57 Private Declare Function GdipGetImageEncodersSize Lib "gdiplus" (numEncoders As Long, Size As Long) As Long
     58 Private Declare Function GdipGetImageEncoders Lib "gdiplus" (ByVal numEncoders As Long, ByVal Size As Long, Encoders As Any) As Long
     59  
     60 Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
     61 Private Declare Function lstrlenW Lib "kernel32" (ByVal psString As Any) As Long
     62 Private Declare Function CLSIDFromString Lib "ole32" (ByVal lpszProgID As Long, pCLSID As Any) As Long
     63 Private Declare Function GdipBitmapSetResolution Lib "gdiplus" (ByVal Bitmap As Long, ByVal xdpi As Single, ByVal ydpi As Single) As Long
     64  
     65  
     66 Public Enum ImageFileFormat
     67     Bmp = 1
     68     Jpg = 2
     69     Png = 3
     70     Gif = 4
     71 End Enum
     72  
     73 Public Function SaveStdPicToFile(Stdpic As StdPicture, ByVal FileName As String, _
     74                               Optional ByVal FileFormat As ImageFileFormat = Jpg, _
     75                               Optional ByVal JpgQuality As Long = 80, _
     76                               Optional Resolution As Single) As Boolean
     77                               
     78     Dim CLSID(3)        As Long
     79     Dim Bitmap          As Long
     80     Dim Token           As Long
     81     Dim Gsp             As GdiplusStartupInput
     82  
     83     Gsp.GdiplusVersion = 1                      'GDI+ 1.0版本
     84     GdiplusStartup Token, Gsp                   '初始化GDI+
     85     GdipCreateBitmapFromHBITMAP Stdpic.Handle, Stdpic.hPal, Bitmap
     86     If Bitmap <> 0 Then                          '说明我们成功的将StdPic对象转换为GDI+的Bitmap对象了
     87         GdipBitmapSetResolution Bitmap, Resolution, Resolution
     88         Select Case FileFormat
     89         Case ImageFileFormat.Bmp
     90             If Not GetEncoderClsID("Image/bmp", CLSID) = -1 Then
     91                 SaveStdPicToFile = (GdipSaveImageToFile(Bitmap, StrPtr(FileName), CLSID(0), ByVal 0) = 0)
     92             End If
     93         Case ImageFileFormat.Jpg                    'JPG格式可以设置保存的质量
     94             Dim aEncParams()        As Byte
     95             Dim uEncParams          As EncoderParameters
     96             If GetEncoderClsID("Image/jpeg", CLSID) <> -1 Then
     97                 uEncParams.Count = 1                                        ' 设置自定义的编码参数,这里为1个参数
     98                 If JpgQuality < 0 Then
     99                     JpgQuality = 0
    100                 ElseIf JpgQuality > 100 Then
    101                     JpgQuality = 100
    102                 End If
    103                 ReDim aEncParams(1 To Len(uEncParams))
    104                 With uEncParams.Parameter
    105                     .NumberOfValues = 1
    106                     .Type = EncoderParameterValueTypeLong                   ' 设置参数值的数据类型为长整型
    107                     Call CLSIDFromString(StrPtr(EncoderQuality), .GUID(0))  ' 设置参数唯一标志的GUID,这里为编码品质
    108                     .Value = VarPtr(JpgQuality)                                ' 设置参数的值:品质等级,最高为100,图像文件大小与品质成正比
    109                 End With
    110                 CopyMemory aEncParams(1), uEncParams, Len(uEncParams)
    111                 SaveStdPicToFile = (GdipSaveImageToFile(Bitmap, StrPtr(FileName), CLSID(0), aEncParams(1)) = 0)
    112             End If
    113         Case ImageFileFormat.Png
    114             If Not GetEncoderClsID("Image/png", CLSID) = -1 Then
    115                 SaveStdPicToFile = (GdipSaveImageToFile(Bitmap, StrPtr(FileName), CLSID(0), ByVal 0) = 0)
    116             End If
    117         Case ImageFileFormat.Gif
    118             If Not GetEncoderClsID("Image/gif", CLSID) = -1 Then                '如果原始的图像是24位,则这个函数会调用系统的调色板来将图像转换为8位,转换的效果会不尽人意,但也有可能系统不自动转换,保存失败
    119                 SaveStdPicToFile = (GdipSaveImageToFile(Bitmap, StrPtr(FileName), CLSID(0), ByVal 0) = 0)
    120             End If
    121         End Select
    122     End If
    123     GdipDisposeImage Bitmap      '注意释放资源
    124     GdiplusShutdown Token       '关闭GDI+。
    125 End Function
    126  
    127  
    128 Private Function GetEncoderClsID(strMimeType As String, ClassID() As Long) As Long
    129     Dim Num         As Long
    130     Dim Size        As Long
    131     Dim I           As Long
    132     Dim Info()      As ImageCodecInfo
    133     Dim Buffer()    As Byte
    134     GetEncoderClsID = -1
    135     GdipGetImageEncodersSize Num, Size               '得到解码器数组的大小
    136     If Size <> 0 Then
    137        ReDim Info(1 To Num) As ImageCodecInfo       '给数组动态分配内存
    138        ReDim Buffer(1 To Size) As Byte
    139        GdipGetImageEncoders Num, Size, Buffer(1)            '得到数组和字符数据
    140        CopyMemory Info(1), Buffer(1), (Len(Info(1)) * Num)     '复制类头
    141        For I = 1 To Num             '循环检测所有解码
    142            If (StrComp(PtrToStrW(Info(I).MimeType), strMimeType, vbTextCompare) = 0) Then         '必须把指针转换成可用的字符
    143                CopyMemory ClassID(0), Info(I).ClassID(0), 16  '保存类的ID
    144                GetEncoderClsID = I      '返回成功的索引值
    145                Exit For
    146            End If
    147        Next
    148     End If
    149 End Function
    150  
    151 Private Function PtrToStrW(ByVal lpsz As Long) As String
    152     Dim Out         As String
    153     Dim Length      As Long
    154     Length = lstrlenW(lpsz)
    155     If Length > 0 Then
    156         Out = StrConv(String$(Length, vbNullChar), vbUnicode)
    157         CopyMemory ByVal Out, ByVal lpsz, Length * 2
    158         PtrToStrW = StrConv(Out, vbFromUnicode)
    159     End If
    160 End Function
  • 相关阅读:
    【Python3网络爬虫开发实战】3.1.2-处理异常
    02018_StringBuffer练习
    富文本编辑器可以如何直接复制word的图文内容到编辑器中?
    TinyMCE可以如何直接复制word的图文内容到编辑器中?
    wangEditor可以如何直接复制word的图文内容到编辑器中?
    xhEditor可以如何直接复制word的图文内容到编辑器中?
    FCKEditor可以如何直接复制word的图文内容到编辑器中?
    KindEditor可以如何直接复制word的图文内容到编辑器中?
    CKEditor可以如何直接复制word的图文内容到编辑器中?
    百度编辑器可以如何直接复制word的图文内容到编辑器中?
  • 原文地址:https://www.cnblogs.com/lingqingxue/p/10353581.html
Copyright © 2020-2023  润新知