Dim L%, T%, R%, B%, I%, Off As POINTAPI If Degree.Value < 90 Then L = 1: T = 2: R = 4: B = 3 ElseIf Degree.Value < 180 Then L = 2: T = 4: R = 3: B = 1 ElseIf Degree.Value < 270 Then L = 4: T = 3: R = 1: B = 2 Else L = 3: T = 1: R = 2: B = 4 End If
Off.x = -P(L).x Off.y = -P(T).y
For I = 1 To 4 P(I).x = P(I).x + Off.x P(I).y = P(I).y + Off.y Next
PicDest.Cls PlgBlt PicDest.hDC, P(1), PicSrc.hDC, 0, 0, PicSrc.ScaleWidth, PicSrc.ScaleHeight, 0, 0, 0 PicDest.Refresh End Sub
我怀疑是hbmMask, xMask, yMask的问题.
PlgBlt 这个函数只有NT系列才有,,Win9X好像不支持
Win9X好像不支持? 他没有说找不到DLL入口.......... 难道是个占位函数?
PlgBlt: 【VB声明】 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【说明】 复制一幅位图,同时将其转换成一个平行四边形。利用它可对位图进行旋转处理 【返回值】 Long,非零表示成功,零表示失败。会设置GetLastError 【备注】 如果对源图象应用了旋转或剪切处理,这个函数的执行就会失败。可用GetDeviceCaps判断这个函数是否得到了一个特定设备场景的支持【参数表】 hdcDest -------- Long,图象使用的目标设备场景 lpPoint -------- POINTAPI,POINTAPI结构数组中使用的第一个条目。第一个点对应于一个平行四边形左上角位置;第二个点代表右下角位置;第三个点代表左下角位置;第四个点是在前三个点的基础上导出的 hdcSrc --------- Long,图象的源设备场景 nXSrc,nYSrc ---- Long,源图象左上角的x,y坐标,采用逻辑坐标系统表示 nWidth,nHeight - Long,源图象大小,用逻辑坐标表示 hbmMask -------- Long,一个可选的句柄,指向一个单色掩模。如设定了这个参数,那么只有与掩模值1对应的二进制位才会传输到目的地 xMask,yMask ---- Long,掩模位图欲使用区域左上角的x,y坐标 适用平台 Windows NT
那个问题是没治了,我再问一个: PictureBox.Picture和PictureBox.Image有什么区别? As Picture和StdPicture和IPictureDisp有什么区别?
//StdPicture和IPictureDisp有什么区别实际上是一样的//PictureBox.Picture和PictureBox.ImageProperty Image As IPictureDisp 只读 VB.PictureBox 的成员 返回一个 Microsoft Windows 提供的句柄到一个持久性位图。 (其实就是当前显示的图形,和picturebox大小相同)Property Picture As IPictureDisp VB.PictureBox 的成员 返回/设置控件中显示的图形。 (和picturebox的大小没有关系,它的大小取决于图片文件)
明白了。 还是前面的问题。 我把WIN XP
还没写完就发出去了,怎么回事。 我把WIN XP的GDI32.DLL复制过来,并在声明中加上了路径,这回VB说找不到文件! File not found: F:\GDI32.DLL 我可以肯定路径没有错误. 有谁知道怎么回事?
终于做出来了,但是还有两个问题: 1、旋转时有麻点。(这是我的算法不好,要改就得全改) 2、下划线的两行,本来是应该从0开始,但改成0就会下标超界。谁能告诉我其中的原因。VERSION 5.00 Object = "{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}#2.0#0"; "MSCOMCTL.OCX" Begin VB.Form Form1 Caption = "Form1" ClientHeight = 5325 ClientLeft = 1755 ClientTop = 2055 ClientWidth = 6330 LinkTopic = "Form1" ScaleHeight = 355 ScaleMode = 3 'Pixel ScaleWidth = 422 Begin MSComctlLib.Slider Degree Height = 630 Left = 105 TabIndex = 2 Top = 180 Width = 4560 _ExtentX = 8043 _ExtentY = 1111 _Version = 393216 LargeChange = 10 Max = 360 TickStyle = 3 End Begin VB.PictureBox PicDest AutoRedraw = -1 'True Height = 3450 Left = 2400 ScaleHeight = 226 ScaleMode = 3 'Pixel ScaleWidth = 140 TabIndex = 1 Top = 855 Width = 2160 End Begin VB.PictureBox PicSrc AutoRedraw = -1 'True Height = 3450 Left = 210 Picture = "Form1.frx":0000 ScaleHeight = 226 ScaleMode = 3 'Pixel ScaleWidth = 140 TabIndex = 0 Top = 855 Width = 2160 End End Attribute VB_Name = "Form1" Attribute VB_GlobalNameSpace = False Attribute VB_Creatable = False Attribute VB_PredeclaredId = True Attribute VB_Exposed = False Option Explicit Private Declare Function GetObject Lib "gdi32" Alias "GetObjectA" (ByVal hObject As Long, ByVal nCount As Long, lpObject As Any) As Long Private Declare Function CreateCompatibleDC Lib "gdi32" (ByVal hDC As Long) As Long Private Declare Function SelectObject Lib "gdi32" (ByVal hDC As Long, ByVal hObject As Long) As Long Private Declare Function GetDIBits Lib "gdi32" (ByVal aHDC As Long, ByVal hBitmap As Long, ByVal nStartScan As Long, ByVal nNumScans As Long, lpBits As Any, lpBI As BITMAPINFO, ByVal wUsage As Long) As Long Private Declare Function DeleteDC Lib "gdi32" (ByVal hDC As Long) As Long Private Declare Function SetDIBitsToDevice Lib "gdi32" (ByVal hDC As Long, ByVal x As Long, ByVal y As Long, ByVal dx As Long, ByVal dy As Long, ByVal SrcX As Long, ByVal SrcY As Long, ByVal Scan As Long, ByVal NumScans As Long, Bits As Any, BitsInfo As BITMAPINFO, ByVal wUsage As Long) As Long Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long) Private Type BITMAP '14 bytes bmType As Long bmWidth As Long bmHeight As Long bmWidthBytes As Long bmPlanes As Integer bmBitsPixel As Integer bmBits As Long End Type Private Type BITMAPINFOHEADER '40 bytes 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 Private Type RGBQUAD rgbBlue As Byte rgbGreen As Byte rgbRed As Byte rgbReserved As Byte End Type Private Type BITMAPINFO bmiHeader As BITMAPINFOHEADER bmiColors(255) As RGBQUAD End Type Private Type POINTAPI x As Long y As Long End Type Const BI_RGB = 0& Const DIB_RGB_COLORS = 0 ' color table in RGBs Const Pi# = 3.14159265358979Private Sub Degree_Scroll() Dim Image As StdPicture Set Image = PicSrc.Image
Dim BM As BITMAP GetObject Image.Handle, Len(BM), BM Dim BI As BITMAPINFO With BI.bmiHeader .biSize = Len(BI.bmiHeader) .biWidth = BM.bmWidth .biHeight = BM.bmHeight .biPlanes = BM.bmPlanes .biBitCount = BM.bmBitsPixel .biCompression = BI_RGB
Dim LineBytes As Long LineBytes = ((.biWidth * .biBitCount + 31&) And &HFFFFFFE0) \ 8 .biSizeImage = LineBytes * .biHeight
ReDim MapData(0 To LineBytes - 1, 0 To .biHeight - 1) As Byte
Dim L%, T%, R%, B%, I%, Off As POINTAPI If Degree.Value < 90 Then L = 1: T = 2: R = 4: B = 3 ElseIf Degree.Value < 180 Then L = 2: T = 4: R = 3: B = 1 ElseIf Degree.Value < 270 Then L = 4: T = 3: R = 1: B = 2 Else L = 3: T = 1: R = 2: B = 4 End If
Off.x = -P(L).x Off.y = -P(T).y
For I = 1 To 4 P(I).x = P(I).x + Off.x P(I).y = P(I).y + Off.y Next
PicDest.Width = P(R).x + 4 PicDest.Height = P(B).y + 4 End With
Dim NewBI As BITMAPINFO With NewBI.bmiHeader NewBI = BI .biWidth = P(R).x .biHeight = P(B).y Dim NewLineBytes As Long NewLineBytes = ((.biWidth * .biBitCount + 31&) And &HFFFFFFE0) \ 8 ReDim NewMap(0 To NewLineBytes - 1, 0 To .biHeight - 1) As Byte End With
With BI.bmiHeader If .biBitCount < 8 Then Exit Sub Dim M As Long, N As Long For N = 1 To .biHeight - 1 '-------------------------------- For M = 1 To .biWidth - 1 '-------------------------------- CopyMemory NewMap((.biBitCount \ 8) * CLng(Off.x + M * CosRad + N * SinRad), CLng(Off.y - M * SinRad + N * CosRad)), MapData((.biBitCount \ 8) * M, N), .biBitCount \ 8
Next
Next End With
With NewBI.bmiHeader SetDIBitsToDevice PicDest.hDC, 0, 0, .biWidth, .biHeight, 0, 0, 0, .biHeight, NewMap(0, 0), NewBI, DIB_RGB_COLORS End With PicDest.Refresh End Sub
Object = "{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}#2.0#0"; "MSCOMCTL.OCX"
Begin VB.Form Form1
BorderStyle = 1 'Fixed Single
Caption = "Form1"
ClientHeight = 5055
ClientLeft = 2190
ClientTop = 2565
ClientWidth = 6420
LinkTopic = "Form1"
MaxButton = 0 'False
MinButton = 0 'False
ScaleHeight = 337
ScaleMode = 3 'Pixel
ScaleWidth = 428
Begin MSComctlLib.Slider Degree
Height = 420
Left = 15
TabIndex = 2
Top = 105
Width = 4215
_ExtentX = 7435
_ExtentY = 741
_Version = 393216
LargeChange = 30
Max = 360
TickStyle = 3
End
Begin VB.PictureBox PicDest
AutoRedraw = -1 'True
Height = 2145
Left = 2100
ScaleHeight = 139
ScaleMode = 3 'Pixel
ScaleWidth = 126
TabIndex = 1
Top = 1005
Width = 1950
End
Begin VB.PictureBox PicSrc
AutoRedraw = -1 'True
Height = 1620
Left = 225
Picture = "Form1.frx":0000
ScaleHeight = 104
ScaleMode = 3 'Pixel
ScaleWidth = 75
TabIndex = 0
Top = 840
Width = 1185
End
Begin VB.Label Label1
AutoSize = -1 'True
Caption = "旋转360度"
BeginProperty Font
Name = "宋体"
Size = 15.75
Charset = 134
Weight = 400
Underline = 0 'False
Italic = 0 'False
Strikethrough = 0 'False
EndProperty
Height = 315
Left = 4545
TabIndex = 3
Top = 150
Width = 1440
End
End
Attribute VB_Name = "Form1"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = True
Attribute VB_Exposed = False
Option Explicit
Private Declare Function PlgBlt Lib "gdi32" (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
Private Type POINTAPI
x As Long
y As Long
End Type
Const Pi# = 3.14159265358979Private Sub Degree_Scroll()
Label1 = "旋转" & Degree.Value & "度"
Dim P(1 To 4) As POINTAPI, Rad#
Rad = Degree.Value * Pi / 180
'P(1).x = 0
'P(1).y = 0
P(2).x = Cos(Rad) * PicSrc.ScaleWidth
P(2).y = -Sin(Rad) * PicSrc.ScaleWidth
P(3).x = Sin(Rad) * PicSrc.ScaleHeight
P(3).y = Cos(Rad) * PicSrc.ScaleHeight
P(4).x = P(2).x + P(3).x
P(4).y = P(2).y + P(3).y
Dim L%, T%, R%, B%, I%, Off As POINTAPI
If Degree.Value < 90 Then
L = 1: T = 2: R = 4: B = 3
ElseIf Degree.Value < 180 Then
L = 2: T = 4: R = 3: B = 1
ElseIf Degree.Value < 270 Then
L = 4: T = 3: R = 1: B = 2
Else
L = 3: T = 1: R = 2: B = 4
End If
Off.x = -P(L).x
Off.y = -P(T).y
For I = 1 To 4
P(I).x = P(I).x + Off.x
P(I).y = P(I).y + Off.y
Next
PicDest.Width = P(R).x + 4
PicDest.Height = P(B).y + 4
PicDest.Cls
PlgBlt PicDest.hDC, P(1), PicSrc.hDC, 0, 0, PicSrc.ScaleWidth, PicSrc.ScaleHeight, 0, 0, 0
PicDest.Refresh
End Sub
他没有说找不到DLL入口..........
难道是个占位函数?
【VB声明】
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【说明】
复制一幅位图,同时将其转换成一个平行四边形。利用它可对位图进行旋转处理 【返回值】
Long,非零表示成功,零表示失败。会设置GetLastError 【备注】
如果对源图象应用了旋转或剪切处理,这个函数的执行就会失败。可用GetDeviceCaps判断这个函数是否得到了一个特定设备场景的支持【参数表】
hdcDest -------- Long,图象使用的目标设备场景 lpPoint -------- POINTAPI,POINTAPI结构数组中使用的第一个条目。第一个点对应于一个平行四边形左上角位置;第二个点代表右下角位置;第三个点代表左下角位置;第四个点是在前三个点的基础上导出的 hdcSrc --------- Long,图象的源设备场景 nXSrc,nYSrc ---- Long,源图象左上角的x,y坐标,采用逻辑坐标系统表示 nWidth,nHeight - Long,源图象大小,用逻辑坐标表示 hbmMask -------- Long,一个可选的句柄,指向一个单色掩模。如设定了这个参数,那么只有与掩模值1对应的二进制位才会传输到目的地 xMask,yMask ---- Long,掩模位图欲使用区域左上角的x,y坐标
适用平台
Windows NT
PictureBox.Picture和PictureBox.Image有什么区别?
As Picture和StdPicture和IPictureDisp有什么区别?
只读
VB.PictureBox 的成员
返回一个 Microsoft Windows 提供的句柄到一个持久性位图。
(其实就是当前显示的图形,和picturebox大小相同)Property Picture As IPictureDisp
VB.PictureBox 的成员
返回/设置控件中显示的图形。
(和picturebox的大小没有关系,它的大小取决于图片文件)
还是前面的问题。
我把WIN XP
我把WIN XP的GDI32.DLL复制过来,并在声明中加上了路径,这回VB说找不到文件!
File not found: F:\GDI32.DLL
我可以肯定路径没有错误.
有谁知道怎么回事?
如果想在win98下实现图形的旋转,可以不用PlgBlt,根据解析几何进行换算即可,当然速度要慢一些
http://vbnew.www21.cnidc.cn/wz/qcwz1/list.asp?id=1102
根据解析几何进行换算,这个我到会.
我用getpixel,setpixel做过,太慢.
用dib,我正在做,又碰到问题了:
GetDIBits Picture1.hdc, Picture1.Image.Handle, 0, Picture1.ScaleHeight, MapData(0), BM, 0
mapdata是位图数据(足够大),bm是bitmapinfo.
返回值为0.请问是什么原因?千万不要说win98不支持...
另外,我想只得到bm(根据bm确定redim mapdata(多大?) ),该怎么做?
但是他没有bitmapinfo结构,他的bits是只包含数据区,还是包含整个位图的字节?
1、旋转时有麻点。(这是我的算法不好,要改就得全改)
2、下划线的两行,本来是应该从0开始,但改成0就会下标超界。谁能告诉我其中的原因。VERSION 5.00
Object = "{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}#2.0#0"; "MSCOMCTL.OCX"
Begin VB.Form Form1
Caption = "Form1"
ClientHeight = 5325
ClientLeft = 1755
ClientTop = 2055
ClientWidth = 6330
LinkTopic = "Form1"
ScaleHeight = 355
ScaleMode = 3 'Pixel
ScaleWidth = 422
Begin MSComctlLib.Slider Degree
Height = 630
Left = 105
TabIndex = 2
Top = 180
Width = 4560
_ExtentX = 8043
_ExtentY = 1111
_Version = 393216
LargeChange = 10
Max = 360
TickStyle = 3
End
Begin VB.PictureBox PicDest
AutoRedraw = -1 'True
Height = 3450
Left = 2400
ScaleHeight = 226
ScaleMode = 3 'Pixel
ScaleWidth = 140
TabIndex = 1
Top = 855
Width = 2160
End
Begin VB.PictureBox PicSrc
AutoRedraw = -1 'True
Height = 3450
Left = 210
Picture = "Form1.frx":0000
ScaleHeight = 226
ScaleMode = 3 'Pixel
ScaleWidth = 140
TabIndex = 0
Top = 855
Width = 2160
End
End
Attribute VB_Name = "Form1"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = True
Attribute VB_Exposed = False
Option Explicit
Private Declare Function GetObject Lib "gdi32" Alias "GetObjectA" (ByVal hObject As Long, ByVal nCount As Long, lpObject As Any) As Long
Private Declare Function CreateCompatibleDC Lib "gdi32" (ByVal hDC As Long) As Long
Private Declare Function SelectObject Lib "gdi32" (ByVal hDC As Long, ByVal hObject As Long) As Long
Private Declare Function GetDIBits Lib "gdi32" (ByVal aHDC As Long, ByVal hBitmap As Long, ByVal nStartScan As Long, ByVal nNumScans As Long, lpBits As Any, lpBI As BITMAPINFO, ByVal wUsage As Long) As Long
Private Declare Function DeleteDC Lib "gdi32" (ByVal hDC As Long) As Long
Private Declare Function SetDIBitsToDevice Lib "gdi32" (ByVal hDC As Long, ByVal x As Long, ByVal y As Long, ByVal dx As Long, ByVal dy As Long, ByVal SrcX As Long, ByVal SrcY As Long, ByVal Scan As Long, ByVal NumScans As Long, Bits As Any, BitsInfo As BITMAPINFO, ByVal wUsage As Long) As Long
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
Private Type BITMAP '14 bytes
bmType As Long
bmWidth As Long
bmHeight As Long
bmWidthBytes As Long
bmPlanes As Integer
bmBitsPixel As Integer
bmBits As Long
End Type
Private Type BITMAPINFOHEADER '40 bytes
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
Private Type RGBQUAD
rgbBlue As Byte
rgbGreen As Byte
rgbRed As Byte
rgbReserved As Byte
End Type
Private Type BITMAPINFO
bmiHeader As BITMAPINFOHEADER
bmiColors(255) As RGBQUAD
End Type
Private Type POINTAPI
x As Long
y As Long
End Type
Const BI_RGB = 0&
Const DIB_RGB_COLORS = 0 ' color table in RGBs
Const Pi# = 3.14159265358979Private Sub Degree_Scroll()
Dim Image As StdPicture
Set Image = PicSrc.Image
Dim BM As BITMAP
GetObject Image.Handle, Len(BM), BM Dim BI As BITMAPINFO
With BI.bmiHeader
.biSize = Len(BI.bmiHeader)
.biWidth = BM.bmWidth
.biHeight = BM.bmHeight
.biPlanes = BM.bmPlanes
.biBitCount = BM.bmBitsPixel
.biCompression = BI_RGB
Dim LineBytes As Long
LineBytes = ((.biWidth * .biBitCount + 31&) And &HFFFFFFE0) \ 8
.biSizeImage = LineBytes * .biHeight
ReDim MapData(0 To LineBytes - 1, 0 To .biHeight - 1) As Byte
GetDIBits PicSrc.hDC, Image.Handle, 0, .biHeight, MapData(0, 0), BI, DIB_RGB_COLORS
Dim Rad#, SinRad#, CosRad#
Rad = Degree.Value * Pi / 180
SinRad = Sin(Rad)
CosRad = Cos(Rad)
Dim P(1 To 4) As POINTAPI
'P(1).x = 0
'P(1).y = 0
P(2).x = CosRad * PicSrc.ScaleWidth
P(2).y = -SinRad * PicSrc.ScaleWidth
P(3).x = SinRad * PicSrc.ScaleHeight
P(3).y = CosRad * PicSrc.ScaleHeight
P(4).x = P(2).x + P(3).x
P(4).y = P(2).y + P(3).y
Dim L%, T%, R%, B%, I%, Off As POINTAPI
If Degree.Value < 90 Then
L = 1: T = 2: R = 4: B = 3
ElseIf Degree.Value < 180 Then
L = 2: T = 4: R = 3: B = 1
ElseIf Degree.Value < 270 Then
L = 4: T = 3: R = 1: B = 2
Else
L = 3: T = 1: R = 2: B = 4
End If
Off.x = -P(L).x
Off.y = -P(T).y
For I = 1 To 4
P(I).x = P(I).x + Off.x
P(I).y = P(I).y + Off.y
Next
PicDest.Width = P(R).x + 4
PicDest.Height = P(B).y + 4
End With
Dim NewBI As BITMAPINFO
With NewBI.bmiHeader
NewBI = BI
.biWidth = P(R).x
.biHeight = P(B).y
Dim NewLineBytes As Long
NewLineBytes = ((.biWidth * .biBitCount + 31&) And &HFFFFFFE0) \ 8
ReDim NewMap(0 To NewLineBytes - 1, 0 To .biHeight - 1) As Byte
End With
With BI.bmiHeader
If .biBitCount < 8 Then Exit Sub
Dim M As Long, N As Long For N = 1 To .biHeight - 1
'--------------------------------
For M = 1 To .biWidth - 1
'-------------------------------- CopyMemory NewMap((.biBitCount \ 8) * CLng(Off.x + M * CosRad + N * SinRad), CLng(Off.y - M * SinRad + N * CosRad)), MapData((.biBitCount \ 8) * M, N), .biBitCount \ 8
Next
Next
End With
With NewBI.bmiHeader
SetDIBitsToDevice PicDest.hDC, 0, 0, .biWidth, .biHeight, 0, 0, 0, .biHeight, NewMap(0, 0), NewBI, DIB_RGB_COLORS
End With
PicDest.Refresh
End Sub