写了一个小程序,里面要用到图片缩放,baidu了一下,发现GDI+不错,所以找了个模块,试了一下效果不错,但今天无意中发现一个很奇怪的问题,程序调试状态下,缩放1张500K的图,缩放后大小在10K以下,效果很好,但如果编译运行的话,处理同样的图片,大小就变成了30多K,搞不清楚什么情况,如果在编译选项中设置为"P",是可以了,但"P"代码执行效率偏低,所以还是想找到问题的原因!
写了个测试程序,问题依旧!具体代码如下:
这是窗体代码:
需要添加两个Picture控件Private Const STRETCH_HALFTONE = 4
Private Declare Function SetStretchBltMode Lib "gdi32" (ByVal hdc As Long, ByVal nStretchMode As Long) As Long
Private Declare Function StretchBlt Lib "gdi32" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As Long, ByVal xSrc As Long, ByVal ySrc As Long, ByVal nSrcWidth As Long, ByVal nSrcHeight As Long, ByVal dwRop As Long) As LongPrivate Sub SavePic(ByVal fPath, fName As String) '------------------------------------------------
Pic1.Picture = LoadPicture(fPath & fName)
Pic2.Move 0, 0, 200, 200
SetStretchBltMode Pic2.hdc, STRETCH_HALFTONE
SetStretchBltMode Me.hdc, STRETCH_HALFTONE
StretchBlt Pic2.hdc, 0, 0, Pic2.ScaleWidth, Pic2.ScaleHeight, Pic1.hdc, 0, 0, Pic1.ScaleWidth, Pic1.ScaleHeight, vbSrcCopy
StretchBlt Me.hdc, 0, 0, Me.ScaleWidth, Me.ScaleHeight, Pic1.hdc, 0, 0, Pic1.ScaleWidth, Pic1.ScaleHeight, vbSrcCopy
'保存为 jpg
SaveJPG Pic2.Image, App.Path & "\" & fName & ".jpg", 75
Set Pic1.Picture = Nothing
Set Pic2.Picture = Nothing
MsgBox "ok"
End SubPrivate Sub Form_Load()
Call SavePic("e:\", "1.jpg")
End Sub这是模块源码:
Option ExplicitPrivate Type GUID
Data1 As Long
Data2 As Integer
Data3 As Integer
Data4(0 To 7) As Byte
End TypePrivate Type GdiplusStartupInput
GdiplusVersion As Long
DebugEventCallback As Long
SuppressBackgroundThread As Long
SuppressExternalCodecs As Long
End TypePrivate Type EncoderParameter
GUID As GUID
NumberOfValues As Long
type As Long
Value As Long
End TypePrivate Type EncoderParameters
Count As Long
Parameter As EncoderParameter
End TypePrivate Declare Function GdiplusStartup Lib "GDIPlus" (token As Long, inputbuf As GdiplusStartupInput, Optional ByVal outputbuf As Long = 0) As LongPrivate Declare Function GdiplusShutdown Lib "GDIPlus" (ByVal token As Long) As LongPrivate Declare Function GdipCreateBitmapFromHBITMAP Lib "GDIPlus" (ByVal hbm As Long, ByVal hpal As Long, BITMAP As Long) As LongPrivate Declare Function GdipDisposeImage Lib "GDIPlus" (ByVal Image As Long) As LongPrivate Declare Function GdipSaveImageToFile Lib "GDIPlus" (ByVal Image As Long, ByVal filename As Long, clsidEncoder As GUID, encoderParams As Any) As LongPrivate Declare Function CLSIDFromString Lib "ole32" (ByVal str As Long, id As GUID) As LongPublic Sub SaveJPG(ByVal pict As StdPicture, ByVal filename As String, Optional ByVal quality As Byte)
Dim tSI As GdiplusStartupInput
Dim lRes As Long
Dim lGDIP As Long
Dim lBitmap As Long ' 初始化 GDI+
tSI.GdiplusVersion = 1
lRes = GdiplusStartup(lGDIP, tSI)
If lRes = 0 Then
' 从句柄创建 GDI+ 图像
lRes = GdipCreateBitmapFromHBITMAP(pict.Handle, 0, lBitmap)
If lRes = 0 Then
Dim tJpgEncoder As GUID
Dim tParams As EncoderParameters
'初始化解码器的GUID标识
CLSIDFromString StrPtr("{557CF401-1A04-11D3-9A73-0000F81EF32E}"), tJpgEncoder
' 设置解码器参数
tParams.Count = 1
With tParams.Parameter ' Quality
' 得到Quality参数的GUID标识
CLSIDFromString StrPtr("{1D5BE4B5-FA4A-452D-9CDD-5DB35105E7EB}"), .GUID
.NumberOfValues = 1
.type = 4
.Value = VarPtr(quality)
End With
'保存图像
lRes = GdipSaveImageToFile(lBitmap, StrPtr(filename), tJpgEncoder, tParams)
' 销毁GDI+图像
GdipDisposeImage lBitmap
End If
'销毁 GDI+
GdiplusShutdown lGDIP End If
If lRes Then
Err.Raise 5, , "不能保存这个图像:" & lRes
Exit Sub
End If
End Sub
写了个测试程序,问题依旧!具体代码如下:
这是窗体代码:
需要添加两个Picture控件Private Const STRETCH_HALFTONE = 4
Private Declare Function SetStretchBltMode Lib "gdi32" (ByVal hdc As Long, ByVal nStretchMode As Long) As Long
Private Declare Function StretchBlt Lib "gdi32" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As Long, ByVal xSrc As Long, ByVal ySrc As Long, ByVal nSrcWidth As Long, ByVal nSrcHeight As Long, ByVal dwRop As Long) As LongPrivate Sub SavePic(ByVal fPath, fName As String) '------------------------------------------------
Pic1.Picture = LoadPicture(fPath & fName)
Pic2.Move 0, 0, 200, 200
SetStretchBltMode Pic2.hdc, STRETCH_HALFTONE
SetStretchBltMode Me.hdc, STRETCH_HALFTONE
StretchBlt Pic2.hdc, 0, 0, Pic2.ScaleWidth, Pic2.ScaleHeight, Pic1.hdc, 0, 0, Pic1.ScaleWidth, Pic1.ScaleHeight, vbSrcCopy
StretchBlt Me.hdc, 0, 0, Me.ScaleWidth, Me.ScaleHeight, Pic1.hdc, 0, 0, Pic1.ScaleWidth, Pic1.ScaleHeight, vbSrcCopy
'保存为 jpg
SaveJPG Pic2.Image, App.Path & "\" & fName & ".jpg", 75
Set Pic1.Picture = Nothing
Set Pic2.Picture = Nothing
MsgBox "ok"
End SubPrivate Sub Form_Load()
Call SavePic("e:\", "1.jpg")
End Sub这是模块源码:
Option ExplicitPrivate Type GUID
Data1 As Long
Data2 As Integer
Data3 As Integer
Data4(0 To 7) As Byte
End TypePrivate Type GdiplusStartupInput
GdiplusVersion As Long
DebugEventCallback As Long
SuppressBackgroundThread As Long
SuppressExternalCodecs As Long
End TypePrivate Type EncoderParameter
GUID As GUID
NumberOfValues As Long
type As Long
Value As Long
End TypePrivate Type EncoderParameters
Count As Long
Parameter As EncoderParameter
End TypePrivate Declare Function GdiplusStartup Lib "GDIPlus" (token As Long, inputbuf As GdiplusStartupInput, Optional ByVal outputbuf As Long = 0) As LongPrivate Declare Function GdiplusShutdown Lib "GDIPlus" (ByVal token As Long) As LongPrivate Declare Function GdipCreateBitmapFromHBITMAP Lib "GDIPlus" (ByVal hbm As Long, ByVal hpal As Long, BITMAP As Long) As LongPrivate Declare Function GdipDisposeImage Lib "GDIPlus" (ByVal Image As Long) As LongPrivate Declare Function GdipSaveImageToFile Lib "GDIPlus" (ByVal Image As Long, ByVal filename As Long, clsidEncoder As GUID, encoderParams As Any) As LongPrivate Declare Function CLSIDFromString Lib "ole32" (ByVal str As Long, id As GUID) As LongPublic Sub SaveJPG(ByVal pict As StdPicture, ByVal filename As String, Optional ByVal quality As Byte)
Dim tSI As GdiplusStartupInput
Dim lRes As Long
Dim lGDIP As Long
Dim lBitmap As Long ' 初始化 GDI+
tSI.GdiplusVersion = 1
lRes = GdiplusStartup(lGDIP, tSI)
If lRes = 0 Then
' 从句柄创建 GDI+ 图像
lRes = GdipCreateBitmapFromHBITMAP(pict.Handle, 0, lBitmap)
If lRes = 0 Then
Dim tJpgEncoder As GUID
Dim tParams As EncoderParameters
'初始化解码器的GUID标识
CLSIDFromString StrPtr("{557CF401-1A04-11D3-9A73-0000F81EF32E}"), tJpgEncoder
' 设置解码器参数
tParams.Count = 1
With tParams.Parameter ' Quality
' 得到Quality参数的GUID标识
CLSIDFromString StrPtr("{1D5BE4B5-FA4A-452D-9CDD-5DB35105E7EB}"), .GUID
.NumberOfValues = 1
.type = 4
.Value = VarPtr(quality)
End With
'保存图像
lRes = GdipSaveImageToFile(lBitmap, StrPtr(filename), tJpgEncoder, tParams)
' 销毁GDI+图像
GdipDisposeImage lBitmap
End If
'销毁 GDI+
GdiplusShutdown lGDIP End If
If lRes Then
Err.Raise 5, , "不能保存这个图像:" & lRes
Exit Sub
End If
End Sub
从Byte改为Long,就可以了!
郁闷的问题!