1 谁说VB不能转,我转,我转,我转转
前些时候和朋友交流图片旋转的问题,朋友讲VB做图片旋转根本是开玩笑,速度根本跟不上,我就不信这个邪,经过N长时间搜罗资料,终于得到了下面的方法,DIB法,其实我们处理图片速度慢不是VB慢,而是你的方法有问题,所以写到这里大家共同研究一下:
一个Module
Type BITMAPINFOHEADER '40 bytes,这个大家可以看看BMP的格式
BmSize As Long
BmWidth As Long
BmHeight As Long
BmPlanes As Integer
BmBitCount As Integer
BmCompression As Long
BmSizeImage As Long
BmXPelsPerMeter As Long
BmYPelsPerMeter As Long
BmClrUsed As Long
BmClrImportant As Long
End Type
Type BITMAPINFO
BmHeader As BITMAPINFOHEADER
End Type
'下面是两个操作DIB的函数
Declare Sub GetDIBits Lib "GDI32" (ByVal hDC&, ByVal hBitmap&, ByVal nStartScan&, ByVal nNumScans&, lpBits As Any, lpBI As BITMAPINFO, ByVal wUsage&)
Declare Sub SetDIBits Lib "GDI32" (ByVal hDC&, ByVal hBitmap&, ByVal nStartScan&, ByVal nNumScans&, lpBits As Any, lpBI As BITMAPINFO, ByVal wUsage&)
下面是窗体部分,两个Picture,Picture1装载一个图片,要小点的哦,呵呵,Picture2显示旋转结果,一个HScroll
,下面是代码:
Sub RotatePicDI(SrcPic As PictureBox, DestPic As PictureBox, A As Double)
Dim SrcInfo As BITMAPINFO, DesInfo As BITMAPINFO
Dim X&, Y&, CA As Double, SA As Double, nX&, nY&
Dim sW&, sH&, sW2&, sH2&, dW&, dH&, dW2&, dH2&
Const Pi = 0.017453292519943
CA = Cos(A * Pi * -1): SA = Sin(A * Pi * -1)
sW = SrcPic.ScaleWidth
sH = SrcPic.ScaleHeight
dW = DestPic.ScaleWidth
dH = DestPic.ScaleHeight
sW2 = sW / 2: sH2 = sH / 2
dW2 = dW / 2: dH2 = dH / 2
SrcInfo.BmHeader.BmSize = 40
SrcInfo.BmHeader.BmWidth = sW
SrcInfo.BmHeader.BmHeight = -sH
SrcInfo.BmHeader.BmPlanes = 1
SrcInfo.BmHeader.BmBitCount = 32
SrcInfo.BmHeader.BmSizeImage = 3 * sW * sH
LSet DesInfo = SrcInfo
DesInfo.BmHeader.BmWidth = dW
DesInfo.BmHeader.BmHeight = -dH
DesInfo.BmHeader.BmSizeImage = 3 * dW * dH
ReDim SrcPix(0, sW - 1, sH - 1) As Long
ReDim DesPix(0, dW - 1, dH - 1) As Long
Call GetDIBits(SrcPic.hDC, SrcPic.Image, 0&, sH, SrcPix(0, 0, 0), SrcInfo, 0&)
For Y = 0 To dH - 1
For X = 0 To dW - 1
nX = CA * (X - dW2) - SA * (Y - dH2) + sW2
nY = SA * (X - dW2) + CA * (Y - dH2) + sH2
If nX > -1 And nY > -1 And nX < sW And nY < sH Then
DesPix(0, X, Y) = SrcPix(0, nX, nY)
End If
Next
Next
Call SetDIBits(DestPic.hDC, DestPic.Image, 0&, dH, DesPix(0, 0, 0), DesInfo, 0&)
DestPic.Picture = DestPic.Image
End Sub
Private Sub HScroll1_Scroll()
RotatePicDI Picture1, Picture2, HScroll1.Value
End Sub
拖动HScroll1看看结果吧
【声明】
Private Declare Function PlgBlt Lib "gdi32" Alias "PlgBlt" (ByVal hdcDest As Long, lpPoint As POINTAPI, ByVal hdcSrc As Long, ByVal nXSrc As Long, ByVal nYSrc As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hbmMask As Long, ByVal xMask As Long, ByVal yMask As Long) As Long
下面介绍一下实现方法:进入VISUAL BASIC中,建立一个新的窗体。在窗体中加入两个图画盒控件(Picture1和Picture2),设置它们的Name属性为PicSource和PicTarget,并为PicSource图画盒的Picture属性设置一幅位图。再在窗体中加入一个按钮(CommandRotorate),设置它的Caption属性为“旋转”。然后加入以下代码:
Option Explicit
Const Pi = 3.14
Private Sub CommandRototate_Click()
Dim x As Integer, y As Integer
Dim X1 As Integer, Y1 As Integer
Dim X2 As Double, Y2 As Double
Dim X3 As Double, Y3 As Double
Dim JiaoDu As Double
Dim HuDu As Double
JiaoDu = 45 '角度
HuDu = JiaoDu * Pi / 180 '弧度
PicSource.ScaleMode = vbPixels
PicTarget.ScaleMode = vbPixels
For x = 0 To PicTarget.ScaleWidth
X1 = x - PicTarget.ScaleWidth \ 2
For y = 0 To PicTarget.ScaleHeight
Y1 = y - PicTarget.ScaleHeight \ 2
X2 = X1 * Cos(-HuDu) + Y1 * Sin(-HuDu)
Y2 = Y1 * Cos(-HuDu) - X1 * Sin(-HuDu)
X3 = X2 + PicSource.ScaleWidth \ 2
Y3 = Y2 + PicSource.ScaleHeight \ 2
If X3 > 0 And X3 < PicSource.ScaleWidth - 1 And Y3 > 0 And Y3 <
PicSource.ScaleHeight - 1 Then
PicTarget.PSet (x, y), PicSource.Point(X3, Y3)
End If
Next y
Next x
End Sub
运行后,按下“旋转”按钮,可以见到源图画盒中的位图旋转45度后进入到目标图画盒中。如果要改变旋转的角度,只需将JiaoDu变量设置为相应值即可。