编程基础 软件工程 JAVA .NET Delphi Visual C/C++ C++Builder Visual Basic C/C++ PowerBuilder 汇编语言 数据结构&算法 破解与加脱壳 移动开发编程开发技巧与经验
返回首页

GDI+下的文字绘制

时间:2013-09-18来源: 作者: 点击:

   这段时间群里的不少网友提到了[如何在图像上绘制文字]、[文字水印]等问题,当然实现的代码在网上是可以找得到的,但大部分是被人封装到了类里,如果对 GDI+不是很了解可能用起来不太方便,这里我给大家简单介绍下GDI+绘制文字的实现过程,希望对大家有所帮助。

   GDI+绘制文本的核心函数是GdipDrawString,其它GDI+TEXT类函数则用来指定文本特征,我们可以选择任何图像作为显示文本的表面,而呈现对象需要一个BRUSH对象(它指示用什么图案来填充文本)和一个FONT对象,字体可以系统以安装的任意字体,而画笔可以是任意类型的画笔,我们可以选择用纯色、自定义的纹理图案、渐变色等等来绘制文本。GDI+文本绘制总的来说一般按照如下步骤来完成:

1、取得被绘制的图形的graphics对象句柄
2、创建绘制文本的画笔(BRUSH)
3、创建显示文本用的字体(FONT)
4、调用GdipDrawString来显示文本

现在我们就围绕GdipDrawString函数来一一说明,GdipDrawString API声明如下:

DECLARE Long GdipDrawString IN GDIPLUS.DLL;
        Long graphics, String str,;
        Long length, Long thefont,;
        String @layoutRect, ;
        Long StringFormat,;
        Long brush

OK,现在对每个参数进行详细说明;

参数1:graphics,故名思议,graphics对象句柄,这里需要注意的一点就是大家不要把graphics对象和IMAGE对象混淆,比如我要在一个图片上绘制文字,那么首先就是要用GdipLoadImageFromFile来先创建IMAGE对象,如果你直接在IMAGE对象上用GdipDrawString来绘制文字是错误的,所以如果你GdipLoadImageFromFile来创建IMAGE对象后还需要用GdipGetImageGraphicsContext来获得其 graphics对象,然后在graphics对象上进行文字绘制。

参数2:str,要绘制的文本的UNICODE(宽字符)格式,一提到UNICODE格式,大家首先会想到VFP中的    StrCon()函数,这个函数功能十分强大能支持8中不同格式的相互转换,另外要说明的一点就是GDI+中凡是需要对字符串进行处理的部分都要进行UNICODE格式的转换,也许用过GDI+文字绘制的人都碰到过一个问题,就是如果用strcon('字串'+0h00,5)把汉字转换后会出现乱码的现象,造成这个问题的主要问题是strcon()对单双字节混合不完善支持造成的问题,这里我们姑且不去 追究,因为我们可以用MultiByteToWideChar这个API来转换得到真正的UNICODE格式。

参数3:length,要绘制的文本的长度,注意并不是UNICODE(宽字符)格式str的长度。

参数4:thefont,GDI+ FONT对象的句柄,一般用GdipCreateFont来根据事先定义的一个FontFamily对象来创建。

参数5:layoutRect,这是一个GDI+Rect结构,用来确定被绘制内容的起始坐标和被绘制的范围大小,如果把 layoutRect看做是一个矩形的话,那么它是由(x,y)矩形的左上角坐标和这个矩形的宽度、长度4部分组成的,这里需要注意的一点就是layoutRect是一个浮点型的数据结构,在VFP9版本中我们可以用BINTOC(x,'F') 来获得。

参数6:StringFormat,文本格式,如对齐格式。

参数7:brush,画笔对象,没它画不出来,呵呵!


OK,马上来个最简单的,用纯色在表单上绘制一段文字。

API声明:
DECLARE Long GdipDrawString IN GDIPLUS.DLL ;
        Long graphics, String str,;
        Long length, Long thefont,;
        String @layoutRect, ;
        Long StringFormat,;
        Long brush
DECLARE INTEGER GdipCreateStringFormat IN GdiPlus.dll ;
INTEGER formatAttributes, INTEGER language, INTEGER @nFormat
DECLARE INTEGER GdipCreateSolidFill IN GdiPlus.dll;
INTEGER ARGBcolor, INTEGER @brush
DECLARE INTEGER GdipDeleteBrush IN GdiPlus.dll ;
INTEGER brush
DECLARE INTEGER GdipCreateFont IN GdiPlus.dll;
INTEGER fontFamily, SINGLE emSize,;
INTEGER fntstyle, INTEGER unit, INTEGER @fnt
DECLARE INTEGER GdipDeleteFont IN GdiPlus.dll ;
INTEGER fnt
DECLARE INTEGER GdipCreateFontFamilyFromName IN GdiPlus.dll;
STRING familyname, INTEGER FontCollection, INTEGER @FontFamily
DECLARE INTEGER GdipDeleteFontFamily IN GdiPlus.dll ;
INTEGER FontFamily
DECLARE INTEGER GdipCreateFromHWND IN gdiplus.dll ;
INTEGER hWind, INTEGER @graphics
DECLARE INTEGER GdipDeleteGraphics IN GdiPlus.dll ;
INTEGER graphics    
Declare Long MultiByteToWideChar In kernel32 ;
Long iCodePage, Long dwFlags, String @ lpStr, Long iMultiByte, ;
String @ lpWideStr, Long iWideChar
DECLARE INTEGER GdipLoadImageFromFile IN gdiplus.DLL ;
        STRING wFilename, INTEGER @nImage
DECLARE INTEGER GdipSaveImageToFile IN gdiplus.DLL ;
        INTEGER nImage, STRING wFilename, STRING qEncoder, INTEGER nEncoderParamsPtr      
DECLARE INTEGER GdipGetImageGraphicsContext IN gdiplus.DLL ;
        INTEGER nImage, INTEGER @ nGraphics

DECLARE INTEGER GdipCreateHatchBrush IN Gdiplus.dll;
        INTEGER hatchstyle, INTEGER forecol, INTEGER backcol, INTEGER @brush

DECLARE INTEGER GdipGetImageHeight IN gdiplus;
        INTEGER   img,;
        INTEGER @ imgheight
DECLARE INTEGER GdipGetImageWidth IN gdiplus;
        INTEGER   img,INTEGER @ imgwidth


*第一步:指定要绘制的文字
lcText='VFP应用程式算法群--行者孙'
lnLen=2*(Len(lcText)+1)
lcWideStr=Replicate(Chr(0),lnLen)
MultiByteToWideChar(0,0,@lcText,Len(lcText), @lcWideStr,lnLen)
tcText=lcWideStr

*第二步:创建graphics对象
graphics=0
GdipCreateFromHWND(thisform.hwnd,@graphics)&&根据窗口句柄创建graphics对象
*如果是用GdipLoadImageFromFile(ImageFile,@nImage)把文字绘制到图形上的话,还要用
*GdipGetImageGraphicsContext(nImage,@graphics)来得到其句柄。

*第三步:创建绘制文本的画笔(BRUSH)
Brush=0
ucolor=RGB(255,12,25)&&字体颜色
aphpi=100&&透明度
lnColor = CTOBIN(CHR(aphpi)+LEFT(BINTOC(uColor,'4rs'),3),'4s')
GdipCreateSolidFill(lnColor,@brush)

*第四步:创建FontFamily对象
lcFontName='宋体'&&字体名称,必须是已注册的字体
lcFontName=STRCONV(lcFontName+0h00,5)
lnFontFamily=0
GdipCreateFontFamilyFromName(lcFontName,0,@lnFontFamily)

*第五步:创建FONT并指定其格式
lnFont=0
lnFontStyle=1&&字体类型,1加粗
tnSize=20&&字体大小
GdipCreateFont(lnFontFamily,tnSize,lnFontStyle,3,@lnFont)

*第七步:指定StringFormat格式
lnFormatHandle = 0
thAlignment=0&&对其格式 居左
GdipCreateStringFormat(0,0,@lnFormatHandle)

*第八步:指定文本被绘制的区域(layoutRect)
x=30&&绘制文字的左上角坐标
y=40
w=thisform.Width
h=thisform.Height
lcRectangleF=BINTOC(x,'F')+BINTOC(y,'F')+BINTOC(W,'F')+BINTOC(H,'F')

*第九步:绘制文字
GdipDrawString(graphics,tcText,LEN(lcText),lnFont,@lcRectangleF,0,brush)

OK,复制上述代码到表单的按钮里运行即可!

除了使用GdipCreateSolidFill画刷进行最简单的文本绘制外,我们还可以使用不同的画笔刷子来实现不同的文字效果,在GDI+中一般常用的画刷有:
GdipCreateSolidFill               单色画刷
GdipCreateHatchBrush     预设纹理画刷(我知道的只有54种)
GdipCreateTexture    用自定义图形作为纹理进行绘制
LinearGradientBrush           渐变色画刷
PathGradientBrush              通过自由设置中心点实现中心点到路径边界的色彩渐变

关于GDI+文本绘制就说这么多吧,哪天抽空在给大家详细介绍下上面这5种画刷的使用。

 

补充:在图形上写文字     

graphics=0
nimage=0
File_Name='BBB.bmp'
GdipLoadImageFromFile(STRCONV(File_Name + CHR(0),5),@nimage)
lcText='VFP应用程式算法群'
lnLen = 2 * (Len(lcText) + 1)
lcWideStr = Replicate(Chr(0), lnLen)
MultiByteToWideChar(0,0,@lcText,Len(lcText), @lcWideStr,lnLen)
tcText=lcWideStr
lcFontName='黑体'&&字体名称,必须是已注册的字体
lcFontName=STRCONV(lcFontName+CHR(0),5)
lnFontFamily=0
GdipCreateFontFamilyFromName(lcFontName,0,@lnFontFamily)
lnFont=0
lnFontStyle=1&&字体类型,0默认,1加粗,2倾斜3=1+2加粗倾斜 4U 8 S
tnSize=20&&字体大小
GdipCreateFont(lnFontFamily,tnSize,lnFontStyle, 3,@lnFont)
lnFormatHandle = 0
thAlignment=0&&对其格式 居左
GdipCreateStringFormat(0, 0, @lnFormatHandle )
nAlign = lnFormatHandle
brush=0
ucolor1=RGB(0,255,0)&&字体颜色
aphpi=255&&透明度
lnColor1 = CTOBIN(CHR(aphpi)+LEFT(BINTOC(uColor1,'4rs'),3),'4s')
ucolor2=RGB(0,0,0)&&字体颜色
aphpi=255&&透明度
lnColor2 = CTOBIN(CHR(aphpi)+LEFT(BINTOC(uColor2,'4rs'),3),'4s')
GdipCreateHatchBrush(11,lnColor1,lnColor2,@brush)&&建立纹理刷子
x=30&&绘制文字的左上角坐标
y=40
w=0
h=0
GdipGetImageWidth(nImage,@w)
GdipGetImageHeight(nImage,@h)
lcRectangleF=BINTOC(x,'F')+BINTOC(y,'F')+BINTOC(w,'F')+BINTOC(h,'F')
GdipGetImageGraphicsContext (nImage, @Graphics)
GdipDrawString(Graphics, tcText, LEN(lcText), lnFont,@lcRectangleF, 0,brush)
lcEncoder=0h01F47C55041AD3119A730000F81EF32E
GdipSaveImageToFile (nImage, STRCONV('123.jpg',5) + CHR(0), lcEncoder, 0)
GdipDeleteFontFamily(lnFontFamily)
GdipDeleteFont(lnFont)

顶一下
(0)
0%
踩一下
(0)
0%
------分隔线----------------------------
发表评论
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
评价:
表情:
验证码:点击我更换图片
推荐内容