phpimagettftext,绝对详解PHP的imageTtfText()函数
图⽚处理,是许多程序的功能之⼀;⽽⽂字渲染则是绘图的基本组成部分。PHP通过很多扩展库来⽀持图⽚的处理,最常⽤的还是GD库,通过⼀系列imagexxx()函数来提供绘图功能。本⽂专注于⾮常细⼩的⼀点:绘制⽂字。熟悉Win32的⼈都知道,TextOut()就可以轻松显⽰任何⽂字了,然⽽到了PHP的世界⾥,有些事情并不轻松。 1 详细解释imageTtfText()函数
对于PHP绘图初学者,⾸先遇到的⼀个问题就是,imageString()这个函数并不⽀持汉字的绘制。这往往会给⼊门者当头⼀棒,不过不要着急,因为还有⼀个imageTtfText()函数,这个函数能绘制UTF-8编码的字符串,当然可以绘制汉字了。然⽽使⽤它并不⼗分简单。先来看看其原型声明:
⼀共有8个参数,缺⼀不可,⽽且官⽅⽂档这些参数的解释并不透彻,这⾥笔者尽⼒做更详细清晰的解释:
(1)$image这个是画布资源,⽆需再解释;
(2)$size,官⽅⽂档的解释是,字体⼤⼩,其长度单位依赖于GD库的版本,对于GD1来说是像素,对于GD2来说是磅(point)。现在⼀般都是GD2了,那么这个磅究竟是什么意思呢?这涉及到字体设计的基本知识。
简单来说,磅是⼀个长度度量单位,如果把⼀英⼨等分成72份,每⼀份就是1磅。这⾥需要强调的是,磅是个绝对物理单位,与显⽰设备⽆关。
⽽像素呢?像素没有固定的⼤⼩,⽽是与分辨率相关,⾼分辨率的显⽰器像素就很⼩,如iphone视⽹膜屏上⼀个像素的⼤⼩要⽐普通LCD 显⽰器的像素⼩很多。然⽽有些东西是不存在分辨率这个概念的,如单纯的位图图⽚,它的最⼩组成部分就是像素,本⾝也是通过每个像素的颜⾊值来定义的。把同样的图⽚显⽰在不同分辨率的显⽰器上,最终呈现出的⼤⼩是不同的。
操作位图时,以像素位单位最精确合理,那么使⽤GD2库的时候,如何绘制⼤⼩为20像素的字呢?也就是多少磅才能等于20个像素呢?这必须通过分辨率才能计算出来,⽽问题是位图本⾝并没有分辨率的概念。
现在把问题返回来,如果给定$size=20磅,那么imageTtfText()绘制完成时,究竟会占⽤多少像素。⽆论如何,imageTtfText()最终还是要把⽂字绘制落实到具体的位图像素上。
1磅 = PPI/72 个像素
这个问题确实⾮常棘⼿,此函数内部必然会使⽤某个分辨率PPI来计算被渲染的像素区域。⽽GD2库却没有提供任何让⽤户设置或者读取这个分辨率的⽅法。那么,我们只能动⼿测试了。使⽤不同的磅值绘制⽂字,然后测量⽂字占据的像素,通过公式:
PPI = (72*像素数)/磅值。实验得出的结论是:
1磅==>4像素, PPI=2882磅==>5像素, PPI=1803磅==>7像素, PPI=1684磅==>8像素, PPI=1445磅==>9像素, PPI=129.66磅
==>10像素, PPI=1207磅==>11像素, PPI=113.142857142868磅==>12像素, PPI=1089磅==>14像素, PPI=11210磅==>15像素, PPI=10811磅==>16像素, PPI=104.7272727272712磅==>17像素, PPI=10213磅==>18像素, PPI=99.69230769230814磅==>19像素, PPI=97.71428571428615磅==>21像素, PPI=100.816磅==>22像素, PPI=9917磅==>23像素,
PPI=97.41176470588218磅==>25像素, PPI=10019磅==>26像素, PPI=98.52631578947420磅==>27像素, PPI=97.221磅==>28像素, PPI=9622磅==>29像素, PPI=94.90909090909123磅==>30像素, PPI=93.91304347826124磅==>32像素,
PPI=9625磅==>33像素, PPI=95.0426磅==>34像素, PPI=94.15384615384627磅==>35像素, PPI=93.33333333333328磅==>36像素, PPI=92.57142857142929磅==>38像素, PPI=94.34482758620730磅==>39像素, PPI=93.631磅==>40像素,
PPI=92.90322580645232磅==>41像素, PPI=92.2533磅==>43像素, PPI=93.81818181818234磅==>44像素,
PPI=93.17647058823535磅==>46像素, PPI=94.62857142857136磅==>47像素, PPI=9437磅==>48像素,
php初学者项目PPI=93.40540540540538磅==>48像素, PPI=90.94736842105339磅==>50像素, PPI=92.30769230769240磅==>51像素, PPI=91.841磅==>52像素, PPI=91.31707317073242磅==>53像素, PPI=90.85714285714343磅==>55像素,
PPI=92.09302325581444磅==>56像素, PPI=91.63636363636445磅==>57像素, PPI=91.246磅==>58像素,
PPI=90.78260869565247磅==>60像素, PPI=91.91489361702148磅==>62像素, PPI=9349磅==>63像素,
PPI=92.57142857142950磅==>63像素, PPI=90.7251磅==>64像素, PPI=90.35294117647152磅==>67像素,
PPI=92.76923076923153磅==>68像素, PPI=92.37735849056654磅==>69像素, PPI=9255磅==>70像素,
PPI=91.63636363636456磅==>71像素, PPI=91.28571428571457磅==>72像素, PPI=90.947368421
05358磅==>74像素, PPI=91.86206896551759磅==>75像素, PPI=91.52542372881460磅==>76像素, PPI=91.261磅==>77像素,
PPI=90.88524590163962磅==>78像素, PPI=90.5806451612963磅==>79像素, PPI=90.28571428571464磅==>81像素, PPI=91.12565磅==>83像素, PPI=91.93846153846266磅==>84像素, PPI=91.63636363636467磅==>85像素,
PPI=91.3432835820968磅==>86像素, PPI=91.05882352941269磅==>86像素, PPI=89.73913043478370磅==>88像素, PPI=90.51428571428671磅==>90像素, PPI=91.26760563380372磅==>91像素, PPI=9173磅==>92像素,
PPI=90.73972602739774磅==>93像素, PPI=90.486486486486
可见当⼤于46磅时,PPI稳定在90,⽽⼩于46磅时,PPI⼀直在微变。
所以,如果你想绘制20个像素⼤⼩的字体,那么必须设置$size参数为:14.5磅。
另外需要注意的是,$size并不完全对应字体的显⽰⼤⼩,因为同样的$size,不同的字符占据的空间并不是⼀样的。例如,汉字“国”的宽度会⽐数字1的宽度⼤得多,对于标点符号,则更是这样,半⾓和全⾓符号也不同。
总之,使⽤imageTtfText()不可能精确控制到像素级别,只能⼤概。这也算是⽮量字体的⼀个⼩缺陷。
(3)$angle是旋转⾓度。这个官⽹解释的⽐较清楚,需要说明有两点:⼀是⾓度单位是度⽽不是弧度,⼆是旋转的中⼼点就是参数$x,$y。
(4)(5)$x,$y 被绘制字符串的第⼀个字符的基线点。单位是像素。这⾥涉及到字体设计的基本知识--基线。这个点绝对不是左上⾓,⽽具体是什么取决于所使⽤的字体是如何设计的。对于宋体、楷体、⿊体等常见的字体中的汉字,这个点⼤概位于字体的左下部分;⽽对于英⽂字母和标点符号,则各不相同。如下图:
(6)$color 字体的颜⾊,不多解释。
(7)$fontfile 字体⽂件。也就是包含trueType字体字模的⽂件,如楷体字体⽂件f。这种⽂件的格式是有标准规范的,⽽且与平台⽆关。所以可以直接把Windows系统的字体⽂件拷贝到Linux下使⽤。
(8)$text 要渲染的字符串。需要注意必须是UTF-8编码的字符串。说到字符串不得不提PHP的string数据类型。虽然名为string,其实PHP语⾔本⾝并不认识各种字符编码,它只是简单的把string看做是动态增长的“字节”数组,例如strlen()就是返回的字节数。⽽我们知道除了ASCII编码的字符和字节是相同
的外,⼏乎没有其他字符编码中的字符对应⼀个字节,例如⼀个汉字的UTF-8编码占⽤3个字节。⾄于怎么解释其中的字符编码,需要专门的库函数如iconv_strlen()。如果字符串使⽤字⾯量,那么其所在的php源⽂件就必须编码为UTF-8存储。
2 ⼏个⼩技巧
(1)字处理软件的复杂之处
尽管这个函数可以显⽰字符串,但是针对于字处理软件(如Word)来说,并不能使⽤。因为⼀旦涉及到对其的问题,此函数即不能使⽤了。因为它不能处理字间距,当然也就⽆法实现分散对齐等功能。再加上每⾏的“避⾸尾”(如,不能位于⾏⾸)要求,做好字处理并不简单。
变通的⽅式是,⾸先通过复杂的公式计算出各个字符的准确位置,然后针对每⼀个字符调⽤此函数。
(2)如何显⽰加粗字体
对于本⾝就有粗体的字体⽂件来说,这不存在任何问题,只要使⽤粗体⽂件就可以了。问题是很多字体⽂件并没有针对粗体单独设计。GD 库中也没有⼀个能加粗显⽰的函数。其解决⽅法说出来有点可笑,就是针对每个字符绘制两次,第⼆次绘制时的$x会第⼀次的$x多1个像素即可。
本⽂原创发布php中⽂⽹,转载请注明出处,感谢您的尊重!
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论