最近在做一个将文字和图片合成的功能,期间接触到不少方法,显示尝试了js中控制canvas的drawimage的方法,这个方法简单有效,然后接触了PHP的GD图像库。接下来又看到一篇利用php将文字和图片转变成pdf,然后在转为图片的方法。估计这种方法能够很好的对文字实现控制。
在使用PHP库中的时候遇到几个问题,尤其是关于imagettfbbox和imagettftext中fontsize的问题。
先看一个基本的函数 getimagesize-取得图像的大小,这个函数不会用到GD图像库。这个函数将返回一个具有四个单元的数组,
0——包含图像宽度的像素值
1——包含图像高度的像素值
2——图像类型的标记 1=GIF 2=JPG 3=PNG 4=SWF 5=PSD 6=BMP 7=TIFF 8=TIFF 9=JPC 10=JP2 11=JPX 12=JB2 13=SWC 14=IFF 15 = WBMP 16 =XBM
3——文本字符串 内容为 ”height="yyy" width="xxx" “,可直接用于IMG标记。
在简单查询PHP的官方文档可以发现对于imagettftext和imagettfbbox的解释如下
imagettfbbox--size是像素单位的字体
imagettftext ----- 字体的尺寸根据gd的版本,为像素尺寸(GD1)或点(磅)尺寸(GD2)。
接下来简单做一些测试。。
$text="我的我的我的我的我的";
$fontsize = 24;//24磅值
$fontsize_px = 32;//像素值
$font = './MSYHBD.TTF';
$white = imagecolorallocate($bg, 255, 255, 255);
$fontBox = imagettfbbox($fontsize_px, 0, $font, $text);
echo "<br />";
echo "用像素32 查看多少像素值 如果是十个字 那么应该就死320像素——————————";
经过测试 发现imagettfbbox这个函数,实际上输入的也是磅值,但是返回的是像素,经过测试 像素和磅值基本上满足 像素 = 磅值*96/72 磅值越大 误差就越大 通常72磅值如果写10个,误差在5像素,这个误差尚不清楚是是字体设计的问题,还是什么问题。
稍微简单的测试了一下在300磅值写10字 应该是400像素*10=4000像素,但是得到的结果是3978,少了22像素。
然后我再用150磅值写了10个字,得到的结果是1989像素,正好同比例少了一半,变成了11像素。
最后我利用300磅值,写了20个字,也就是400像素*20=8000像素,结果得到的是7978像素,还是少了22像素。
所以用这个函数,可以得出两个结论。
第一个,传入的size是字体的磅值,但是最后返回的结果是字体的像素。
第二个,每一磅,像素会与实际的损失每一磅损失0.0763像素左右,想平常用的20号磅值,可以自己补个1-2个像素值,30磅值也仅仅只差2.24个像素值而已,所以如果你是强迫症的确可以改一改。
至于为什么有有误差,问题就设计到字体设计了。。这里就不再追究了和深入讨论了。
至于imagettftext中的size 肯定是磅值,所以在设计的时候要注意区分和理解。
关于文字在图片中居中的问题,可以通过获得图片的width height,然后利用imagettfbbox获得想要写入的文字的width和heigh,通过计算实现居中。
——————————————————————————————————————————————————————————————————————————————
更新::
今天在使用imagettftext这个函数的时候发现一个新的问题,就是换行,似乎他也能考虑在内,于是我绝对对这个函数重新做已测试。看看iamgettftex这个函数究竟能不能用来表示换行后文字的像素的大小。
在imagettftext中换行的表示不能直接插入/n 而是要要将/n用变量代替,或者把\n当成一个字符插入。
比如我想打印
我在
这里的吗
是的
代码如下
$wrap = "\n";
$text = "我在".$wrap."这里的吗"."\n"."是的";
imagettftext($image,$fontsize,0,$x,$y,$fontcolor,$fontfile,$text);
这样输出来的文字就是换行过后的文字。
简单的测试代码如下
<?php
$font = './MSYHBD.TTF';
$fontsize =20;
$text1 = "我在这里";
$hh = "\n";
$text2 = "我在".$hh."这里的吗"."\n"."是的";
$fontBox1 = imagettfbbox($fontsize, 0, $font, $text1);
$fontBox2 = imagettfbbox($fontsize, 0, $font, $text2);
print_r ($fontBox1);
echo "<br />";
print_r ($fontBox2);
?>
浏览其中打印出来的结果,$fontBox2[1] = 83px,可以知道,确实实现了换行,因为fontBox2[1]是文字的左下角的X的值。并且整体的imagettfbbox计算的是文本域的最大区域,有$fontBox2[2]打印出来是107可以知道。