找回密码
 加入
搜索
查看: 18821|回复: 14

[交流] 第九讲 GDI+画刷

[复制链接]
发表于 2013-5-25 15:08:50 | 显示全部楼层 |阅读模式
本帖最后由 seniors 于 2013-6-16 08:00 编辑

GDI+是GDI的升级版吧(我就这样叫他吧),GDI+的功能要比GDI强,只是可能比GDI稍慢些(我没有测试,也不会测试)。
GDI+的操作对象我叫他为画布,在AU3中叫Graphics,所有的图就是画在这个画布上的。
GDI+要用到的工具也有画笔,画刷,路径,选区,只是功能比GDI的要多,而且不要select操作,直接在绘图时指定用哪一个工具就行了。
另外,画图要用到颜色,GDI+的颜色是ARGB格式,能指定透明度。
接下来,不多说,看实例,先重点讲画刷。
一、画刷
GDI+的画刷有5种
0、纯色画刷
_GDIPlus_BrushCreateSolid(颜色)
_GDIPlus_BrushSetFillColor;可以设定画刷颜色

1、阴影画刷
_GDIPlus_HatchBrushCreate(阴影线类型,前景色,背景色)

阴影线类型共有53种,对应数值从0到52
2、纹理画刷
_GDIPlus_TextureCreate( $hImage[, $iWrapMode = 0] )
_GDIPlus_TextureCreate2( $hImage, $nX, $nY, $nWidth, $nHeight[, $iWrapMode = 0] )

$hImage可以从文件获取,也可以是自己绘出的图形
$iWrapMode称为地砖贴法
0 - 无翻转平铺
1 - 当在一行中移动到下一平铺单元时进行水平翻转
2 - 当在一列中移动到下一平铺单元时进行垂直翻转
3 - 行方向水平翻转且列方向垂直翻转
4 - 无平铺
3、径向渐变画刷
_GDIPlus_PathBrushCreate($aPoints[, $iWrapMode = 0])
_GDIPlus_PathBrushCreateFromPath($hPath)

4、线性渐变画刷
_GDIPlus_LineBrushCreate($nX1, $nY1, $nX2, $nY2, $iARGBClr1, $iARGBClr2[, $iWrapMode = 0])
_GDIPlus_LineBrushCreateFromRect($tRectF, $iARGBClr1, $iARGBClr2[, $iGradientMode = 0[, $iWrapMode = 0]])
_GDIPlus_LineBrushCreateFromRectWithAngle($tRectF, $iARGBClr1, $iARGBClr2, $nAngle[, $fIsAngleScalable = True[, $iWrapMode = 0]])

对于渐变画刷,对颜色,位置等都可以设定,函数较多,自己多试多体会吧

实例源码
#include <APIConstants.au3>
#include <WinAPIEx.au3>
#include <GDIPlus.au3>
#include <GDIPlusEx.au3>

Global $hCallback = DllCallbackRegister("YourFunc", "int", "hWnd;uint;wparam;lparam");函数名,返回值,参数
Global $ptrCallback = DllCallbackGetPtr($hCallback)

GUICreate("第九讲", 300, 200)
$nCtrlId = GUICtrlCreatePic("", 0, 0, 300, 200)
$hPicWnd = GUICtrlGetHandle($nCtrlId)
;设置lable控件的处理函数,也就是所谓的控件子类化
Global $hOldProc = _WinAPI_SetWindowLong($hPicWnd, $GWL_WNDPROC, $ptrCallback)

GUISetState()

While 1
        $Msg = GUIGetMsg()
        Switch $Msg
                Case -3
                        ExitLoop
        EndSwitch
WEnd
GUIDelete()
Exit

Func YourFunc($hWnd, $iMsg, $wParam, $lParam)
        Local $au3Dir = RegRead("HKEY_LOCAL_MACHINE\SOFTWARE\AutoIt v3\Autoit", "InstallDir");au3安装目录
        Switch $iMsg
                Case $WM_PAINT
                        Local $tPAINTSTRUCT
                        Local $hDC = _WinAPI_BeginPaint($hWnd, $tPAINTSTRUCT)
                        ;获取控件长高
                        Local $HWND_CX = _WinAPI_GetWindowWidth($hWnd)
                        Local $HWND_CY = _WinAPI_GetWindowHeight($hWnd)
                        ;开始GDI+
                        _GDIPlus_Startup()
                        ;获取画布,这是从DC获取,还可以用_GDIPlus_GraphicsCreateFromHWND($hWnd)从控件句柄获取,使用完成要释放画布_GDIPlus_GraphicsDispose($hGraphics)
                        $hGraphics = _GDIPlus_GraphicsCreateFromHDC($hDC)
                        ;根据画布创建位图对象,我们等会的画图均是针对位图来操作的,也就是没有直接画在画布上,就是所谓的双缓冲画图
                        $hBitmap = _GDIPlus_BitmapCreateFromGraphics($HWND_CX, $HWND_CY, $hGraphics)
                        ;获取位图对象的画布,图就画在位图的画布上
                        $hBackbuffer = _GDIPlus_ImageGetGraphicsContext($hBitmap)
                        ;用颜色0xFFE0E0E0清除画布,GDI+的颜色全是ARGB格式,A是透明度,RGB是红绿蓝,这里FF就是不透明,E0E0E0是红绿蓝成分
                        _GDIPlus_GraphicsClear($hBackbuffer, 0xFFE0E0E0)
                        _GDIPlus_GraphicsSetSmoothingMode($hBackbuffer, 2);平滑模式,2为8*8抗距齿

                        ;纯色画刷_GDIPlus_BrushGetType($hBrush)返回值是0
                        $hBrush = _GDIPlus_BrushCreateSolid(0xFFFF0000)
                        ;还可以用_GDIPlus_BrushSetFillColor($hBrush, $iARGB)设置颜色
                        _GDIPlus_GraphicsFillEllipse($hBackbuffer, 5, 5, 50, 50, $hBrush); GDI+几乎所有操作都是指定画笔或者画刷的,不需要象GDI中先把画笔、画刷选入DC
                        _GDIPlus_BrushDispose($hBrush);画刷用完要释放
                        _GDIPlus_GraphicsDrawString($hBackbuffer, "纯色", 10, 60)

                        ;平移绘图平面,右移60,意思是指,以后的所有操作多会右移60
                        _GDIPlus_GraphicsTranslateTransform($hBackbuffer, 60, 0)
                        ;阴影画刷_GDIPlus_BrushGetType($hBrush)返回值是1
                        $hBrush = _GDIPlus_HatchBrushCreate(52, 0xFFFF0000, 0xFFFFFFFF)
                        ;这里是要右移60的基础上画在5,5坐标,如果不移动的话就是画在65,65坐标
                        _GDIPlus_GraphicsFillEllipse($hBackbuffer, 5, 5, 50, 50, $hBrush)
                        _GDIPlus_BrushDispose($hBrush)
                        _GDIPlus_GraphicsDrawString($hBackbuffer, "阴影", 10, 60)
                        
                        _GDIPlus_GraphicsTranslateTransform($hBackbuffer, 60, 0);平移绘图平面,右移60
                        ;读取纹理填充的图象
                        $hImage = _GDIPlus_ImageLoadFromFile($au3Dir & '\Examples\WinAPIEx\Extras\Tech.bmp')
                        ;纹理画刷_GDIPlus_BrushGetType($hBrush)返回值是2
                        $hBrush = _GDIPlus_TextureCreate($hImage);以图象为填充画刷
                        _GDIPlus_ImageDispose($hImage)
                        _GDIPlus_GraphicsFillEllipse($hBackbuffer, 5, 5, 50, 50, $hBrush)
                        _GDIPlus_BrushDispose($hBrush)
                        _GDIPlus_GraphicsDrawString($hBackbuffer, "纹理", 10, 60)
                        
                        _GDIPlus_GraphicsTranslateTransform($hBackbuffer, 60, 0)
                        ;建立圆形图形路径
                        $hPath = _GDIPlus_PathCreate()
                        _GDIPlus_PathAddEllipse($hPath, 5, 5, 50, 50)
                        ;径向渐变画刷_GDIPlus_BrushGetType($hBrush)返回值是3
                        $hBrush = _GDIPlus_PathBrushCreateFromPath($hPath)
                        _GDIPlus_PathDispose($hPath)
                        ;设置径向渐变的中心点,如果这里不设置的话,就是在圆的中心
                        _GDIPlus_PathBrushSetCenterPoint($hBrush, 20, 20)
                        ;设置中心颜色为白色
                        _GDIPlus_PathBrushSetCenterColor($hBrush, 0xFFFFFFFF)
                        Dim $aColors[2] = [1, 0xFFFF0000]
                        ;设置外围颜色,共一个颜色是红色
                        _GDIPlus_PathBrushSetSurroundColorsWithCount($hBrush, $aColors)
                        _GDIPlus_GraphicsFillEllipse($hBackbuffer, 5, 5, 50, 50, $hBrush)
                        _GDIPlus_BrushDispose($hBrush)
                        _GDIPlus_GraphicsDrawString($hBackbuffer, "径向", 10, 60)
                        
                        _GDIPlus_GraphicsTranslateTransform($hBackbuffer, 60, 0)
                        ;线性渐变画刷_GDIPlus_BrushGetType($hBrush)返回值是4
                        $hBrush = _GDIPlus_LineBrushCreate(0, 0, 10, 10, 0xFFFFFFFF, 0xFFFF0000, 1)
;~                         _GDIPlus_LineBrushSetLinearBlend($hBrush, 0.5)
                        _GDIPlus_GraphicsFillEllipse($hBackbuffer, 5, 5, 50, 50, $hBrush)
                        _GDIPlus_BrushDispose($hBrush)
                        _GDIPlus_GraphicsDrawString($hBackbuffer, "线性", 10, 60)
                        ;========================重置操作
                        _GDIPlus_GraphicsResetTransform($hBackbuffer)
                        _GDIPlus_GraphicsTranslateTransform($hBackbuffer, 0, 80);画布下移80,指以后所有操作下移80
                        _GDIPlus_GraphicsScaleTransform($hBackbuffer, 1, 1.2);画布缩放,指以后所有操作X方向不变,Y方向放大 1.2
                        _GDIPlus_GraphicsRotateTransform($hBackbuffer, 10);画布旋转,指以后所有操作旋转10度

                        $hBrush = _GDIPlus_BrushCreateSolid(0xFFFF0000)
                        _GDIPlus_GraphicsFillEllipse($hBackbuffer, 5, 5, 50, 50, $hBrush);
                        _GDIPlus_BrushDispose($hBrush);
                        _GDIPlus_GraphicsDrawString($hBackbuffer, "纯色", 10, 60)

                        _GDIPlus_GraphicsTranslateTransform($hBackbuffer, 60, 0)
                        $hBrush = _GDIPlus_HatchBrushCreate(50, 0xFFFF0000, 0xFFFFFFFF)
                        _GDIPlus_GraphicsFillEllipse($hBackbuffer, 5, 5, 50, 50, $hBrush)
                        _GDIPlus_BrushDispose($hBrush)
                        _GDIPlus_GraphicsDrawString($hBackbuffer, "阴影", 10, 60)
                        
                        _GDIPlus_GraphicsTranslateTransform($hBackbuffer, 60, 0)
                        $hImage = _GDIPlus_ImageLoadFromFile($au3Dir & '\Examples\WinAPIEx\Extras\Tech.bmp')
                        $hBrush = _GDIPlus_TextureCreate($hImage);以图象为填充画刷
                        _GDIPlus_ImageDispose($hImage)
                        _GDIPlus_GraphicsFillEllipse($hBackbuffer, 5, 5, 50, 50, $hBrush)
                        _GDIPlus_BrushDispose($hBrush)
                        _GDIPlus_GraphicsDrawString($hBackbuffer, "纹理", 10, 60)
                        
                        _GDIPlus_GraphicsTranslateTransform($hBackbuffer, 60, 0)
                        $hPath = _GDIPlus_PathCreate()
                        _GDIPlus_PathAddEllipse($hPath, 5, 5, 50, 50)
                        $hBrush = _GDIPlus_PathBrushCreateFromPath($hPath)
                        _GDIPlus_PathDispose($hPath)
;~                         _GDIPlus_PathBrushSetCenterPoint($hBrush, 20, 20)
                        _GDIPlus_PathBrushSetCenterColor($hBrush, 0xFFFFFFFF)
                        Dim $aColors[2] = [1, 0xFFFF0000]
                        _GDIPlus_PathBrushSetSurroundColorsWithCount($hBrush, $aColors)
                        _GDIPlus_GraphicsFillEllipse($hBackbuffer, 5, 5, 50, 50, $hBrush)
                        _GDIPlus_BrushDispose($hBrush)
                        _GDIPlus_GraphicsDrawString($hBackbuffer, "径向", 10, 60)
                        
                        _GDIPlus_GraphicsTranslateTransform($hBackbuffer, 60, 0)
                        $hBrush = _GDIPlus_LineBrushCreate(0, 0, 10, 10, 0xFFFFFFFF, 0xFFFF0000, 1)
                        _GDIPlus_LineBrushSetLinearBlend($hBrush, 0.5)
                        _GDIPlus_GraphicsFillEllipse($hBackbuffer, 5, 5, 50, 50, $hBrush)
                        _GDIPlus_BrushDispose($hBrush)
                        _GDIPlus_GraphicsDrawString($hBackbuffer, "线性", 10, 60)
                        ;画在位图画布上的图形,在$hBitap上,把$hBitmap画入DC的画布,也就在DC上显示了,双缓冲画图时间再长,画入DC画布就一次操作,图形不会闪烁
                        _GDIPlus_GraphicsDrawImageRect($hGraphics, $hBitmap, 0, 0, 300, 200)
                        _GDIPlus_BitmapDispose($hBitmap)
                        _GDIPlus_GraphicsDispose($hBackbuffer)
                        _GDIPlus_GraphicsDispose($hGraphics)
                        _GDIPlus_Shutdown()
                        _WinAPI_EndPaint($hWnd, $tPAINTSTRUCT)
                        Return 0
        EndSwitch
        Return _WinAPI_CallWindowProc($hOldProc, $hWnd, $iMsg, $wParam, $lParam);没有处理的消息让原先的处理程序处理
EndFunc   ;==>YourFunc

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?加入

×

评分

参与人数 5威望 +8 金钱 +260 贡献 +31 收起 理由
komaau3 + 60 好!!!
xms77 + 50 + 5 第九讲了耶!辛苦~
pusofalse + 5 + 50 + 10 学习了。
lpxx + 50 + 11
afan + 3 +

查看全部评分

发表于 2013-5-25 16:03:42 | 显示全部楼层
SF支持~ 哪天整理成一个目录链接帖,直接精华了~

评分

参与人数 1金钱 +10 收起 理由
lpxx + 10 好主意

查看全部评分

发表于 2013-5-25 18:10:13 | 显示全部楼层
SF支持~ 哪天整理成一个目录链接帖,直接精华了~
afan 发表于 2013-5-25 16:03


正合我意
发表于 2013-5-25 18:58:08 | 显示全部楼层
学习了~
发表于 2013-5-25 19:35:39 | 显示全部楼层
GDI好难啊!年纪大了,不容易记啊
发表于 2013-5-25 20:49:05 | 显示全部楼层
回复 1# seniors
S大,请教一个问题如何设置GDI绘制字体的颜色?
 楼主| 发表于 2013-5-25 21:06:11 | 显示全部楼层
回复 6# xms77


    下一讲的画笔就要讲到
发表于 2013-5-25 21:11:02 | 显示全部楼层
回复 2# afan

等S大教程讲完的时候,有劳超版作个集合链接处理了
发表于 2013-5-25 22:37:31 | 显示全部楼层
学习了。ghd
发表于 2013-5-26 07:15:56 | 显示全部楼层
本帖最后由 netegg 于 2013-5-26 07:20 编辑

尽管看到过,不过确实不错
不过有一点疑问,gdiplusex.au3里已经含有gdiplus了,应该可以不用再加了
 楼主| 发表于 2013-5-26 08:33:20 | 显示全部楼层
回复 10# netegg
好像上次,我的winapiex.au3也包含winapi.au3的,但是有人的却没包含
写着总没事的
发表于 2013-5-26 11:49:00 | 显示全部楼层
回复 11# seniors

用的原版库的话确实没有,我这改了不少东西,甚至包括常量的冲突,我都改了
发表于 2013-8-26 20:30:26 | 显示全部楼层
过来增加人气
发表于 2015-1-17 08:38:02 | 显示全部楼层
过来增加人气。。。。。。。。。。
发表于 2017-4-4 10:42:10 | 显示全部楼层
谁能解释下 怎么那么多的库 常量不用冲突吗??
您需要登录后才可以回帖 登录 | 加入

本版积分规则

QQ|手机版|小黑屋|AUTOIT CN ( 鲁ICP备19019924号-1 )谷歌 百度

GMT+8, 2024-3-29 04:05 , Processed in 0.088840 second(s), 25 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表