本帖最后由 seniors 于 2013-6-16 08:03 编辑
GDI+之文字输出
本来这一讲想讲画笔,结果xms77问的文字颜色怎么设置,我回答错了,所以先讲文字
GDI+文字输出有二种方式
0、方式一 _GDIPlus_GraphicsDrawString方式
_GDIPlus_GraphicsDrawString这个函数里,没有参数设置画刷,其实是可以设置画刷的,只要修改一下
我改成了这样
Func _GraphicsDrawString($hGraphics, $sString, $nX, $nY, $hBrush = 0, $sFont = "Arial", $nSize = 10, $iFormat = 0)
Local $hFormat = _GDIPlus_StringFormatCreate($iFormat)
Local $hFamily = _GDIPlus_FontFamilyCreate($sFont)
Local $hFont = _GDIPlus_FontCreate($hFamily, $nSize)
Local $tLayout = _GDIPlus_RectFCreate($nX, $nY, 0, 0)
Local $aInfo = _GDIPlus_GraphicsMeasureString($hGraphics, $sString, $hFont, $tLayout, $hFormat)
__GDIPlus_BrushDefCreate($hBrush);本来这句是直接建立黑色画刷
Local $aResult = _GDIPlus_GraphicsDrawStringEx($hGraphics, $sString, $hFont, $aInfo[0], $hFormat, $hBrush)
Local $iError = @error
__GDIPlus_BrushDefDispose()
_GDIPlus_FontDispose($hFont)
_GDIPlus_FontFamilyDispose($hFamily)
_GDIPlus_StringFormatDispose($hFormat)
Return SetError($iError, 0, $aResult)
EndFunc ;==>_GraphicsDrawString
这样输出文字就不要麻烦的设置字体等信息了
1、方式二 _GDIPlus_PathAddString方式
就是把字符串转换为路径,通过填充路径或者描边路径来写字
在3.3.7.15版中,描边路径和填充路径函数里直接建立了画笔和画刷,会造成对象没有删除现象,好像在新版本中已经改过来了
我把修改过的贴一下代码
Func _GraphicsDrawPath($hGraphics, $hPath, $hPen = 0)
Local $iTmpErr, $iTmpExt, $aResult
__GDIPlus_PenDefCreate($hPen);使用这种方法,默认是黑色,已经传递的是Pen句柄就不再建立
$aResult = DllCall($ghGDIPDll, "uint", "GdipDrawPath", "hwnd", $hGraphics, "hwnd", $hPen, "hwnd", $hPath)
$iTmpErr = @error
$iTmpExt = @extended
__GDIPlus_PenDefDispose()
If $iTmpErr Then Return SetError($iTmpErr, $iTmpExt, False)
$GDIP_STATUS = $aResult[0]
Return $aResult[0] = 0
EndFunc ;==>_GraphicsDrawPath
Func _GraphicsFillPath($hGraphics, $hPath, $hBrush = 0)
Local $iTmpErr, $iTmpExt, $aResult
__GDIPlus_BrushDefCreate($hBrush);使用这种方法,默认是黑色,已经传递的是Brush句柄就不再建立
$aResult = DllCall($ghGDIPDll, "uint", "GdipFillPath", "hwnd", $hGraphics, "hwnd", $hBrush, "hwnd", $hPath)
$iTmpErr = @error
$iTmpExt = @extended
__GDIPlus_BrushDefDispose()
If $iTmpErr Then Return SetError($iTmpErr, $iTmpExt, False)
$GDIP_STATUS = $aResult[0]
Return $aResult[0] = 0
EndFunc ;==>_GraphicsFillPath
实例中附送了发光字,阴影字的写法,自己体会吧
实例代码
#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)
;设置Pic控件的处理函数,也就是所谓的控件子类化
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)
Switch $iMsg
Case $WM_PAINT
Local $tPAINTSTRUCT;接收_WinAPI_BeginPaint返回的$tagPAINTSTRUCT结构,这结构内部参数我还不清晰
;获取控件DC并消除WM_PAINT消息,这函数一定要用_WinAPI_EndPaint($hWnd, $tPAINTSTRUCT)解除
Local $hDC = _WinAPI_BeginPaint($hWnd, $tPAINTSTRUCT)
;获取控件长高
Local $HWND_CX = _WinAPI_GetWindowWidth($hWnd)
Local $HWND_CY = _WinAPI_GetWindowHeight($hWnd)
_GDIPlus_Startup()
$hGraphics = _GDIPlus_GraphicsCreateFromHDC($hDC)
$hBitmap = _GDIPlus_BitmapCreateFromGraphics($HWND_CX, $HWND_CY, $hGraphics)
$hBackbuffer = _GDIPlus_ImageGetGraphicsContext($hBitmap)
_GDIPlus_GraphicsClear($hBackbuffer, 0xFFE0E0E0)
_GDIPlus_GraphicsSetSmoothingMode($hBackbuffer, 2);光滑模式,2为8*8抗距齿
;DRAWSTRING方式写字
String1($hBackbuffer)
;PathAddString方式写字
String2($hBackbuffer)
_GDIPlus_GraphicsTranslateTransform($hBackbuffer, 0, 120);画布下移
DrawLightLetters($hBackbuffer, "发光", 0, 10, 60, "Arial", 0xFFFFD700)
DrawDarkLetters($hBackbuffer, "阴影", 140, 5, 50, 5, "Arial", 0xFFFFD700)
_GDIPlus_GraphicsDrawImageRect($hGraphics, $hBitmap, 0, 0, $HWND_CX, $HWND_CY)
_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
Func String1($hGraphics)
Local $au3Dir = RegRead("HKEY_LOCAL_MACHINE\SOFTWARE\AutoIt v3\Autoit", "InstallDir");au3安装目录
;纯色画刷_GDIPlus_BrushGetType($hBrush)返回值是0
Local $hBrush = _GDIPlus_BrushCreateSolid(0xFFFF0000)
;还可以用_GDIPlus_BrushSetFillColor($hBrush, $iARGB)设置颜色
_GraphicsDrawString($hGraphics, "A", 0, 0, $hBrush, "Arial", 30)
_GDIPlus_BrushDispose($hBrush);画刷用完要释放
_GraphicsDrawString($hGraphics, "纯色", 10, 40)
;平移绘图平面,右移60,意思是指,以后的所有操作多会右移60
_GDIPlus_GraphicsTranslateTransform($hGraphics, 60, 0)
;阴影画刷_GDIPlus_BrushGetType($hBrush)返回值是1
$hBrush = _GDIPlus_HatchBrushCreate(50, 0xFFFF0000, 0xFFFFFFFF)
;这里是要右移60的基础上画在5,5坐标,如果不移动的话就是画在65,65坐标
_GraphicsDrawString($hGraphics, "B", 0, 0, $hBrush, "Arial", 30)
_GDIPlus_BrushDispose($hBrush)
_GraphicsDrawString($hGraphics, "阴影", 10, 40)
_GDIPlus_GraphicsTranslateTransform($hGraphics, 60, 0);平移绘图平面,右移60
;读取纹理填充的图象
$hImage = _GDIPlus_ImageLoadFromFile($au3Dir & '\Examples\WinAPIEx\Extras\Tech.bmp')
;纹理画刷_GDIPlus_BrushGetType($hBrush)返回值是2
$hBrush = _GDIPlus_TextureCreate($hImage);以图象为填充画刷
_GDIPlus_ImageDispose($hImage)
_GraphicsDrawString($hGraphics, "C", 0, 0, $hBrush, "Arial", 30)
_GDIPlus_BrushDispose($hBrush)
_GraphicsDrawString($hGraphics, "纹理", 10, 40)
_GDIPlus_GraphicsTranslateTransform($hGraphics, 60, 0)
;下面开始是手工画出纹理填充的图案
Local $hBrushBitmap = _GDIPlus_BitmapCreateFromGraphics(10, 4, $hGraphics)
Local $hContext = _GDIPlus_ImageGetGraphicsContext($hBrushBitmap)
$hBrush = _GDIPlus_BrushCreateSolid(0xFF00FF00)
_GDIPlus_GraphicsFillRect($hContext, 0, 0, 10, 4, $hBrush)
_GDIPlus_BrushDispose($hBrush)
$hBrush = _GDIPlus_LineBrushCreate(0, 0, 0, 4, 0x00000000, 0x99000000)
_GDIPlus_GraphicsFillRect($hContext, 0, 0, 10, 4, $hBrush)
_GDIPlus_BrushDispose($hBrush)
_GDIPlus_GraphicsDispose($hContext)
;图案画好,在$hBrushBitmap上
$hBrush = _GDIPlus_TextureCreate($hBrushBitmap, 2);设置图案为纹理画刷,2是垂直翻转铺设
_GDIPlus_BitmapDispose($hBrushBitmap)
_GraphicsDrawString($hGraphics, "D", 0, 0, $hBrush, "Arial", 30)
_GDIPlus_BrushDispose($hBrush)
_GraphicsDrawString($hGraphics, "纹理2", 10, 40)
_GDIPlus_GraphicsTranslateTransform($hGraphics, 60, 0)
;线性渐变画刷_GDIPlus_BrushGetType($hBrush)返回值是4
$hBrush = _GDIPlus_LineBrushCreate(0, 0, 10, 10, 0xFFFFFFFF, 0xFFFF0000, 1)
_GraphicsDrawString($hGraphics, "E", 0, 0, $hBrush, "Arial", 30)
_GDIPlus_BrushDispose($hBrush)
_GDIPlus_GraphicsDrawString($hGraphics, "线性", 10, 40)
;复位画布
_GDIPlus_GraphicsResetTransform($hGraphics)
EndFunc ;==>String1
Func String2($hGraphics)
_GDIPlus_GraphicsTranslateTransform($hGraphics, 0, 60);画布下移
Local $hFamily = _GDIPlus_FontFamilyCreate("Arial")
Local $tLayout = _GDIPlus_RectFCreate(0, 0)
Local $hPath = _GDIPlus_PathCreate()
_GDIPlus_PathAddString($hPath, "F", $tLayout, $hFamily, 1, 40)
$hPen = _GDIPlus_PenCreate(0xFFFF0000, 2)
_GraphicsDrawPath($hGraphics, $hPath, $hPen)
_GDIPlus_PathDispose($hPath)
_GDIPlus_PenDispose($hPen)
_GraphicsDrawString($hGraphics, "描边", 10, 40)
_GDIPlus_GraphicsTranslateTransform($hGraphics, 60, 0)
$hPath = _GDIPlus_PathCreate()
_GDIPlus_PathAddString($hPath, "G", $tLayout, $hFamily, 1, 40)
$hBrush = _GDIPlus_LineBrushCreate(0, 0, 10, 10, 0xFFFFFFFF, 0xFFFF0000, 1)
_GraphicsFillPath($hGraphics, $hPath, $hBrush)
_GDIPlus_PathDispose($hPath)
_GDIPlus_BrushDispose($hBrush)
_GraphicsDrawString($hGraphics, "填充", 10, 40)
_GDIPlus_GraphicsTranslateTransform($hGraphics, 60, 0)
$hPath = _GDIPlus_PathCreate()
_GDIPlus_PathAddString($hPath, "H", $tLayout, $hFamily, 1, 40)
$hPen = _GDIPlus_PenCreate(0xFFFFFFFF, 3)
$hBrush = _GDIPlus_BrushCreateSolid(0xFF000000)
_GraphicsDrawPath($hGraphics, $hPath, $hPen)
_GraphicsFillPath($hGraphics, $hPath, $hBrush)
_GDIPlus_PathDispose($hPath)
_GDIPlus_BrushDispose($hBrush)
_GDIPlus_PenDispose($hPen)
_GraphicsDrawString($hGraphics, "描填2", 10, 40)
_GDIPlus_GraphicsTranslateTransform($hGraphics, 60, 0)
$hPath = _GDIPlus_PathCreate()
_GDIPlus_PathAddString($hPath, "O", $tLayout, $hFamily, 1, 40)
;建立画刷型画笔
$hBrush = _GDIPlus_LineBrushCreate(0, 0, 10, 10, 0xFFFFFFFF, 0xFFFF0000, 1)
$hPen = _GDIPlus_PenCreate2($hBrush, 3)
_GDIPlus_BrushDispose($hBrush)
;画笔建立好了
$hBrush = _GDIPlus_BrushCreateSolid(0xFFFFFF00)
_GraphicsDrawPath($hGraphics, $hPath, $hPen)
_GraphicsFillPath($hGraphics, $hPath, $hBrush)
_GDIPlus_PathDispose($hPath)
_GDIPlus_BrushDispose($hBrush)
_GDIPlus_PenDispose($hPen)
_GraphicsDrawString($hGraphics, "描填3", 10, 40)
_GDIPlus_GraphicsTranslateTransform($hGraphics, 60, 0)
$hPath = _GDIPlus_PathCreate()
_GDIPlus_PathAddString($hPath, "K", $tLayout, $hFamily, 1, 40)
$hPen = _GDIPlus_PenCreate(0xFFFFFFFF, 3)
$hBrush = _GDIPlus_LineBrushCreate(0, 0, 0, 20, 0xFFFFFFFF, 0xFFFF0000, 3)
_GraphicsDrawPath($hGraphics, $hPath, $hPen)
_GraphicsFillPath($hGraphics, $hPath, $hBrush)
_GDIPlus_PathDispose($hPath)
_GDIPlus_BrushDispose($hBrush)
_GDIPlus_PenDispose($hPen)
_GraphicsDrawString($hGraphics, "描填4", 10, 40)
_GDIPlus_FontFamilyDispose($hFamily)
;复位画布
_GDIPlus_GraphicsResetTransform($hGraphics)
EndFunc ;==>String2
Func DrawLightLetters($hGraphics, $letters, $x, $y, $size, $font = "Arial", $FrontColor = 0xFFFFFFFF, $LightColor = 0xFFFFAA00)
;发光字原理,先在一个缩小1/5的画布上写字
Local $hFamily = _GDIPlus_FontFamilyCreate("Arial")
Local $tLayout = _GDIPlus_RectFCreate($x, $y)
Local $hPath = _GDIPlus_PathCreate()
_GDIPlus_PathAddString($hPath, $letters, $tLayout, $hFamily, 1, $size)
Local $pensize = 2
If $size < 90 Then $pensize = 1
Local $hPen = _GDIPlus_PenCreate($LightColor, $pensize)
Local $hBrush = _GDIPlus_BrushCreateSolid($LightColor)
Local $stringsize = _GDIPlus_PathGetWorldBounds($hPath, 0, $hPen)
Local $width = Int($stringsize[2]) + Int($stringsize[0])
Local $height = Int($stringsize[3]) + Int($stringsize[1])
Local $hBitmap = _GDIPlus_BitmapCreateFromGraphics($width / 5, $height / 5, $hGraphics)
Local $hBackbuffer = _GDIPlus_ImageGetGraphicsContext($hBitmap)
;画布缩小
_GDIPlus_GraphicsScaleTransform($hBackbuffer, 1 / 5, 1 / 5)
_GDIPlus_GraphicsTranslateTransform($hBackbuffer, -($pensize / 5), -($pensize / 5))
_GraphicsDrawPath($hBackbuffer, $hPath, $hPen)
_GraphicsFillPath($hBackbuffer, $hPath, $hBrush)
_GDIPlus_PenDispose($hPen)
_GDIPlus_BrushDispose($hBrush)
;再把刚才缩小的图形,画到正常大小的画布,也就是又放大了5倍,这里用了插值方式高质双线形
_GDIPlus_GraphicsSetInterpolationMode($hGraphics, 6);高质双线形$InterpolationModeHighQualityBilinear,
_GDIPlus_GraphicsDrawImageRect($hGraphics, $hBitmap, 0, 0, $width, $height)
;写正常字
$hBrush = _GDIPlus_BrushCreateSolid($FrontColor)
_GraphicsFillPath($hGraphics, $hPath, $hBrush)
_GDIPlus_BrushDispose($hBrush)
_GDIPlus_PathDispose($hPath)
_GDIPlus_BitmapDispose($hBitmap)
_GDIPlus_FontFamilyDispose($hFamily)
_GDIPlus_GraphicsDispose($hBackbuffer)
EndFunc ;==>DrawLightLetters
Func DrawDarkLetters($hGraphics, $letters, $x, $y, $size, $darkMoves = 10, $font = "Arial", $FrontColor = 0xFFFFFFFF, $BackColor = 0x80000000)
;阴影字原理,先在一个缩小1/4的画布上写字,作为阴影
Local $hBrush = _GDIPlus_BrushCreateSolid($BackColor)
Local $hFormat = _GDIPlus_StringFormatCreate()
_GDIPlus_StringFormatSetAlign($hFormat, 0)
Local $hFamily = _GDIPlus_FontFamilyCreate($font)
Local $hFont = _GDIPlus_FontCreate($hFamily, $size, 0)
Local $tLayout = _GDIPlus_RectFCreate($x, $y, 0, 0)
Local $aInfo = _GDIPlus_GraphicsMeasureString($hGraphics, $letters, $hFont, $tLayout, $hFormat)
Local $width = DllStructGetData($aInfo[0], "X") + DllStructGetData($aInfo[0], "Width")
Local $height = DllStructGetData($aInfo[0], "Y") + DllStructGetData($aInfo[0], "Height")
Local $hBitmap = _GDIPlus_BitmapCreateFromGraphics($width / 4, $height / 4, $hGraphics)
Local $hBackbuffer = _GDIPlus_ImageGetGraphicsContext($hBitmap)
_GDIPlus_GraphicsSetTextRenderingHint($hBackbuffer, 4);反走样模式$TextRenderingHintAntiAlias
;画布缩小
_GDIPlus_GraphicsScaleTransform($hBackbuffer, 1 / 4, 1 / 4)
_GDIPlus_GraphicsTranslateTransform($hBackbuffer, $darkMoves, $darkMoves)
_GDIPlus_GraphicsDrawStringEx($hBackbuffer, $letters, $hFont, $aInfo[0], $hFormat, $hBrush)
_GDIPlus_BrushDispose($hBrush)
;再把缩小的图形,画到正常画布,也就是放大了4倍,这里用到插值方法高质量双三次插值,字体边缘有模糊的感觉
_GDIPlus_GraphicsSetInterpolationMode($hGraphics, 7);高质量双三次插值$InterpolationModeHighQualityBicubic
_GDIPlus_GraphicsSetTextRenderingHint($hGraphics, 4);反走样模式$TextRenderingHintAntiAlias
_GDIPlus_GraphicsDrawImageRect($hGraphics, $hBitmap, 0, 0, $width, $height)
;写正常字
$hBrush = _GDIPlus_BrushCreateSolid($FrontColor)
;~ _GDIPlus_GraphicsDrawStringEx($hGraphics, $letters, $hFont, $aInfo[0], $hFormat, $hBrush)
_GraphicsDrawString($hGraphics, $letters, $x, $y, $hBrush, $font, $size)
_GDIPlus_BrushDispose($hBrush)
_GDIPlus_FontDispose($hFont)
_GDIPlus_FontFamilyDispose($hFamily)
_GDIPlus_StringFormatDispose($hFormat)
_GDIPlus_BitmapDispose($hBitmap)
_GDIPlus_GraphicsDispose($hBackbuffer)
EndFunc ;==>DrawDarkLetters
;_GDIPlus_GraphicsDrawString这个函数,我认为他没有设置$hBrush,所以我改成这样就可以用不同的画刷了
Func _GraphicsDrawString($hGraphics, $sString, $nX, $nY, $hBrush = 0, $sFont = "Arial", $nSize = 10, $iFormat = 0)
Local $hFormat = _GDIPlus_StringFormatCreate($iFormat)
Local $hFamily = _GDIPlus_FontFamilyCreate($sFont)
Local $hFont = _GDIPlus_FontCreate($hFamily, $nSize)
Local $tLayout = _GDIPlus_RectFCreate($nX, $nY, 0, 0)
Local $aInfo = _GDIPlus_GraphicsMeasureString($hGraphics, $sString, $hFont, $tLayout, $hFormat)
__GDIPlus_BrushDefCreate($hBrush)
Local $aResult = _GDIPlus_GraphicsDrawStringEx($hGraphics, $sString, $hFont, $aInfo[0], $hFormat, $hBrush)
Local $iError = @error
__GDIPlus_BrushDefDispose()
_GDIPlus_FontDispose($hFont)
_GDIPlus_FontFamilyDispose($hFamily)
_GDIPlus_StringFormatDispose($hFormat)
Return SetError($iError, 0, $aResult)
EndFunc ;==>_GraphicsDrawString
;下面这两个描路径和填充路径,在3.3.9.5中已经更正了,我用的是3.3.7.15画笔和画刷设置不对,可以改成这样的就行了
Func _GraphicsDrawPath($hGraphics, $hPath, $hPen = 0)
Local $iTmpErr, $iTmpExt, $aResult
__GDIPlus_PenDefCreate($hPen)
$aResult = DllCall($ghGDIPDll, "uint", "GdipDrawPath", "hwnd", $hGraphics, "hwnd", $hPen, "hwnd", $hPath)
$iTmpErr = @error
$iTmpExt = @extended
__GDIPlus_PenDefDispose()
If $iTmpErr Then Return SetError($iTmpErr, $iTmpExt, False)
$GDIP_STATUS = $aResult[0]
Return $aResult[0] = 0
EndFunc ;==>_GraphicsDrawPath
Func _GraphicsFillPath($hGraphics, $hPath, $hBrush = 0)
Local $iTmpErr, $iTmpExt, $aResult
__GDIPlus_BrushDefCreate($hBrush)
$aResult = DllCall($ghGDIPDll, "uint", "GdipFillPath", "hwnd", $hGraphics, "hwnd", $hBrush, "hwnd", $hPath)
$iTmpErr = @error
$iTmpExt = @extended
__GDIPlus_BrushDefDispose()
If $iTmpErr Then Return SetError($iTmpErr, $iTmpExt, False)
$GDIP_STATUS = $aResult[0]
Return $aResult[0] = 0
EndFunc ;==>_GraphicsFillPath
|