VB 用GDI+ 如何实现图片的旋转?

图形平滑,边缘可不平滑

模块:

Option Explicit

Public Declare Function GdiplusStartup Lib "gdiplus" (token As Long, inputbuf As GdiplusStartupInput, Optional ByVal outputbuf As Long = 0) As GpStatus
Public Declare Function GdiplusShutdown Lib "gdiplus" (ByVal token As Long) As GpStatus

Public Declare Function GdipCreateFromHDC Lib "gdiplus" (ByVal hDC As Long, graphics As Long) As GpStatus
Public Declare Function GdipDeleteGraphics Lib "gdiplus" (ByVal graphics As Long) As GpStatus
Public Declare Function GdipSetSmoothingMode Lib "gdiplus" (ByVal graphics As Long, ByVal SmoothingMd As SmoothingMode) As GpStatus
Public Declare Function GdipSetInterpolationMode Lib "gdiplus" (ByVal graphics As Long, ByVal interpolation As InterpolationMode) As GpStatus
Public Declare Function GdipSetCompositingQuality Lib "gdiplus" (ByVal graphics As Long, ByVal CompositingQlty As CompositingQuality) As GpStatus

Public Declare Function GdipRotateWorldTransform Lib "gdiplus" (ByVal graphics As Long, ByVal angle As Single, ByVal order As MatrixOrder) As GpStatus
Public Declare Function GdipTranslateWorldTransform Lib "gdiplus" (ByVal graphics As Long, ByVal dx As Single, ByVal dy As Single, ByVal order As MatrixOrder) As GpStatus

Public Declare Function GdipLoadImageFromFile Lib "gdiplus" (ByVal filename As Long, Image As Long) As GpStatus
Public Declare Function GdipDisposeImage Lib "gdiplus" (ByVal Image As Long) As GpStatus
Public Declare Function GdipGetImageWidth Lib "gdiplus" (ByVal Image As Long, Width As Long) As GpStatus
Public Declare Function GdipGetImageHeight Lib "gdiplus" (ByVal Image As Long, Height As Long) As GpStatus
Public Declare Function GdipDrawImageRect Lib "gdiplus" (ByVal graphics As Long, ByVal Image As Long, ByVal x As Single, ByVal y As Single, ByVal Width As Single, ByVal Height As Single) As GpStatus

Public Enum MatrixOrder
MatrixOrderPrepend = 0
MatrixOrderAppend = 1
End Enum

Public Enum QualityMode
QualityModeInvalid = -1
QualityModeDefault = 0
QualityModeLow = 1
QualityModeHigh = 2
End Enum

Public Enum SmoothingMode
SmoothingModeInvalid = QualityModeInvalid
SmoothingModeDefault = QualityModeDefault
SmoothingModeHighSpeed = QualityModeLow
SmoothingModeHighQuality = QualityModeHigh
SmoothingModeNone
SmoothingModeAntiAlias
End Enum

Public Enum InterpolationMode
InterpolationModeInvalid = QualityModeInvalid
InterpolationModeDefault = QualityModeDefault
InterpolationModeLowQuality = QualityModeLow
InterpolationModeHighQuality = QualityModeHigh
InterpolationModeBilinear
InterpolationModeBicubic
InterpolationModeNearestNeighbor
InterpolationModeHighQualityBilinear
InterpolationModeHighQualityBicubic
End Enum

Public Enum CompositingQuality
CompositingQualityInvalid = QualityModeInvalid
CompositingQualityDefault = QualityModeDefault
CompositingQualityHighSpeed = QualityModeLow
CompositingQualityHighQuality = QualityModeHigh
CompositingQualityGammaCorrected
CompositingQualityAssumeLinear
End Enum

Public Type GdiplusStartupInput
GdiplusVersion As Long
DebugEventCallback As Long
SuppressBackgroundThread As Long
SuppressExternalCodecs As Long
End Type

Public Enum GpStatus
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
End Enum

窗体(AutoRedraw=True)
Option Explicit

Dim token As Long
Dim graphics As Long

Dim img As Long, w As Long, h As Long

Private Sub InitGDIPlus()
Dim uInput As GdiplusStartupInput

uInput.GdiplusVersion = 1
If GdiplusStartup(token, uInput) <> Ok Then
MsgBox "GDI+ 初始化错误。程序即将关闭。", vbCritical, "InitError"
End
End If
End Sub

Private Sub TerminateGDIPlus()
GdipDisposeImage img
GdipDeleteGraphics graphics

GdiplusShutdown token
End Sub

Private Sub Form_Load()
InitGDIPlus

GdipCreateFromHDC Me.hDC, graphics
'GdipSetSmoothingMode graphics, SmoothingModeAntiAlias
'GdipSetInterpolationMode graphics, InterpolationModeHighQuality
'GdipSetCompositingQuality graphics, CompositingQualityHighQuality

GdipLoadImageFromFile StrPtr(App.Path & "\1.png"), img
GdipGetImageWidth img, w
GdipGetImageHeight img, h

Rotate 15, graphics, 200, 200
End Sub

Sub Rotate(angle As Single, g As Long, x As Single, y As Integer)
GdipRotateWorldTransform g, angle, MatrixOrderAppend
GdipTranslateWorldTransform g, x, y, MatrixOrderAppend
GdipDrawImageRect g, img, -w, -h / 2, w, h
End Sub

Private Sub Form_Unload(Cancel As Integer)
TerminateGDIPlus
End Sub

GDI功能很强大哦。
有关知识非常多

怎么用vb实现图形的旋转?~

启动vb6建立一个标准exe工程,首先添加两个图片框(picture1和picture2),添加三个命令按钮command1(caption=“正常显示”)、command2(caption=“180度倒立”)、command3(caption=“45度旋转”),双击窗体,写入以下代码:
PrivateConstSRCCOPY=&HCC0020
PrivateConstPi=3.14

PrivateDeclareFunctionSetPixelLib"gdi32"(ByValhdcAsLong, ByValxAsLong,ByValyAsLong,ByValcrColorAsLong)AsLong
PrivateDeclareFunctionGetPixelLib"gdi32"(ByValhdcAsLong, ByValxAsLong,ByValyAsLong)AsLong

PrivateDeclareFunctionStretchBltLib"gdi32"(ByValhdcAsLong, ByValxAsLong,ByValyAsLong,ByValnWidthAsLong,ByValnHeightAsLong, ByValhSrcDCAsLong,ByValxSrcAsLong,ByValySrcAsLong,ByValnSrcWidth AsLong,ByValnSrcHeightAsLong,ByValdwRopAsLong)AsLong

privateSubbmp_rotate(pic1AsPictureBox,pic2AsPictureBox,ByValtheta)‘45度旋转
Dimc1xAsInteger,c1yAsInteger
Dimc2xAsInteger,c2yAsInteger
DimaAsSingle
Dimp1xAsInteger,p1yAsInteger
Dimp2xAsInteger,p2yAsInteger
DimnAsInteger,rAsInteger

c1x=pic1.ScaleWidth\2
c1y=pic1.ScaleHeight\2
c2x=pic2.ScaleWidth\2
c2y=pic2.ScaleHeight\2
Ifc2x$#@60;c2yThenn=c2yElsen=c2x
n=n-1
pic1hDC=pic1.hdc
pic2hDC=pic2.hdc
Forp2x=0Ton
Forp2y=0Ton
Ifp2x=0Thena=Pi/2Elsea=Atn(p2y/p2x)
r=Sqr(1&*p2x*p2x+1&*p2y*p2y)
p1x=r*Cos(a+theta)
p1y=r*Sin(a+theta)
c0&=GetPixel(pic1hDC,c1x+p1x,c1y+p1y)
c1&=GetPixel(pic1hDC,c1x-p1x,c1y-p1y)
c2&=GetPixel(pic1hDC,c1x+p1y,c1y-p1x)
c3&=GetPixel(pic1hDC,c1x-p1y,c1y+p1x)
Ifc0&$#@60;$#@62;-1ThenSetPixelpic2hDC,c2x+p2x,c2y+p2y,c0
Ifc1&$#@60;$#@62;-1ThenSetPixelpic2hDC,c2x-p2x,c2y-p2y,c1
Ifc2&$#@60;$#@62;-1ThenSetPi pic2hDC,c2x+p2y,c2y-p2x,c2
Ifc3&$#@60;$#@62;-1ThenSetPixelpic2hDC,c2x-p2y,c2y+p2x,c3
Next
Next
EndSub

PrivateSubCommand1_Click()‘正常复制
Picture2.Cls
px=Picture1.ScaleWidth
py=Picture1.ScaleHeight
StretchBltPicture2.hdc,px,0,-px,py,Picture1.hdc,0,0,px,py,SRCCOPY
EndSub

PrivateSubCommand2_Click()‘180度倒立
Picture2.Cls
px=Picture1.ScaleWidth
py=Picture1.ScaleHeight
StretchBltPicture2.hdc,0,py,px,-py,Picture1.hdc,0,0,px,py,SRCCOPY
EndSub

PrivateSubCommand3_Click()‘45旋转
Picture2.Cls
Callbmp_rotate(Picture1,Picture2,3.14/4)
EndSub

PrivateSubForm_Load()
OnErrorResumeNext
Me.Caption=App.Title"添加应用程序标题
Me.Left=(Screen.Width-Me.Width)/2
Me.Top=(Screen.Height-Me.Height)/2"窗体具中
Picture1.ScaleMode=3
Picture2.ScaleMode=3
EndSub

'GetPixel和SetPixel太慢了.系统有现成的API用. '本例子需要两个PictureBox,名称分别为PicBack和PicShow.一个CommandButton,名称:Command1. '在PicShow里载入一张图片,然后运行,点command1按钮,你就可以看到效果. 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 NotPI = 3.14159265238 / 180 Private Sub DanRotate(ByRef picDestHdc As Long, xPos As Long, yPos As Long, ByVal Angle As Long, ByRef picSrcHdc As Long, srcXoffset As Long, srcYoffset As Long, ByVal srcWidth As Long, ByVal srcHeight As Long) Dim Points(3) As POINTAPI Dim DefPoints(3) As POINTAPI Dim sSin As Single, sCos As Single Dim ret As Long Points(0).x = -srcWidth * 0.5 Points(0).y = -srcHeight * 0.5 Points(1).x = Points(0).x + srcWidth Points(1).y = Points(0).y Points(2).x = Points(0).x Points(2).y = Points(0).y + srcHeight sSin = Sin(Angle * NotPI) sCos = Cos(Angle * NotPI) DefPoints(0).x = (Points(0).x * sCos - Points(0).y * sSin) + xPos DefPoints(0).y = (Points(0).x * sSin + Points(0).y * sCos) + yPos DefPoints(1).x = (Points(1).x * sCos - Points(1).y * sSin) + xPos DefPoints(1).y = (Points(1).x * sSin + Points(1).y * sCos) + yPos DefPoints(2).x = (Points(2).x * sCos - Points(2).y * sSin) + xPos DefPoints(2).y = (Points(2).x * sSin + Points(2).y * sCos) + yPos PlgBlt picDestHdc, DefPoints(0), picSrcHdc, srcXoffset, srcYoffset, srcWidth, srcHeight, 0, 0, 0 End Sub Private Sub Form_Load() picShow.ScaleMode = vbPixels picBack.ScaleMode = vbPixels End Sub Private Sub Command1_Click() DanRotate picBack.hDC, 100, 100, 45, picShow.hDC, 0, 0, picShow.ScaleWidth,picShow.ScaleHeight '(函数解释)DanRotate 目标(输出)的设备场景,X坐标,Y坐标,旋转角度,源设备场景,源设备场景X坐标,源设备场景Y坐标 picBack.Refresh '刷新窗体 End Sub

#17636643626# 请教:用vb编程如何使图片的背景变为透明? - ******
#臧水# 用Image控件+透明背景的GIF图像可实现.其他格式的图片尤其是真彩色的带阴影的图片要想在VB6实现透明背景则比较困难,代码量大增,运行效率也很低,不推荐使用.VB6毕竟是上个世纪的老古董,你给一辆老爷车装上火箭发动机也开不快的.

#17636643626# vb 怎么图片合并? - ******
#臧水# 你什么意思,让P2的透明部分滤掉然后叠加在前面的图上面吗?方法很多,最简单的方式是使用GDI的TransparentBlt函数.或者用两次BitBlt进行位运算也行.或者MaskBlt也行.以上API的用法都可以在MSDN上查到,其中下面两个的VB声明可...

#17636643626# VB.net什么控件能实现像QQ表情栏那样存放连续图片 - ******
#臧水# VB.NET标准控件库中是没有这个控件的,不过既然提供了picturebox,类似你说的这样的可以连续存放多个图片的控件是可以通过代码动态添加控件来实现,也可以通过vb.net中的GDI+函数代码编程实现.

#17636643626# updatelayeredwindow在VB中的具体用法 - ******
#臧水# 使用了UpdateLayeredWindow方法绘制之后就无法使用vb原有控件了,要自己重新写控件.具体代码可以参考以前网上的一个“99%仿vista窗体”的代码,虽然个人认为这个程序运行后的效果还是不理想(实在太卡了),但是里面基本都是通过gdi+和UpdateLayeredWindow实现的,值得参考.vb本身无法处理png图片,所以在加载png图片是要用byte数组加载.然后用gdi+绘制到窗体或图片框,但是注意控件picture属性是无法保存png图片的.从头到尾都要使用byte数组进行处理保存.

#17636643626# 怎么用VB代码改变图片的像素值 - ******
#臧水# 窗体上放上二个PIcturebox Private Sub Form_Load() Set Picture1.Picture = LoadPicture("请写入你的图片路径") Picture1.AutoRedraw = True Picture1.AutoSize = 1 Picture1.BorderStyle = 0 Picture1.Visible = False Me.ScaleMode = 3 Picture1...

#17636643626# vb.NET 用GDI+画在PictureBox控件里的图怎么保存 - ******
#臧水# '添加模块一个模块声明如下APIPublic Declare Function GdiTransparentBlt Lib "gdi32" (ByVal hdc1 As Long, ByVal x1 As Long, ByVal y1 As Long, ByVal W1 As Long, ByVal H1 As Long, ByVal Hdc2 As Long, ByVal X2 As Long, ByVal Y2 As ...

#17636643626# VB读取、切割,绘制PNG方法 - ******
#臧水# 我想在VB下读取PNG格式图片,比如,一个100*50的图片,然后分析他的像素点 但是VB的图片控件不能直接读取PNG格式的,听说gdiplus.dll可以实现 Dim a As GpStatus a = GdipLoadImageFromFile("F:\1.png", vbUnicode) Option Explicit ...

#17636643626# 如何将PNG图片插入VB控件? - ******
#臧水# 居然看见有人在用VB做游戏了 人才真多啊 对于做叠加 PNG格式图片我也想过(当时考虑的比较麻烦还是PS后改格式了 汗)所以在这只给你列点方法一个是读取数据描点的 但是对与游戏来说 速度相当慢 还有就是用GDI画图 要用API 而且有些论坛上也提出GDI不适合做游戏 然后就是用gvocx控件 如果找得到了话可以用 我好像记得在论坛上有个用Shockwave Flash控件加载PNG实现透明的 不过记不太清步骤了

#17636643626# 怎样用VB写一个可以看矢量大图的 ******
#臧水# >用VB绘制自己的矢量地图 http://www.ccw.com.cn/htm/app/aprog/01_2_27_3.asp -------------------------------------------------------------------------------- >up -------------------------------------------------------------------------------- >建议LZ先了解下Windows的世界坐标转换...

#17636643626# VB的图像处理 - ******
#臧水# 过程一:获得一个在PICTURE控件中打开的图像的所有像素.Public Sub DibGet(ByVal IdSource As Long, XBegin As Long, ByVal YBegin As Long, ByVal XEnd As Long, ByVal YEnd As Long) Dim iBitmap As Long Dim iDC As Long Dim I As ...

为传递更多家电数码信息,若有事情请联系
数码大全网