PHP 动态创建图像

本文最后更新于:2024年3月18日 凌晨

PHP 动态创建图像

  • 动态创建图像的一个流行的应用是实时的微按钮创建图像,通常文字被置于一个空白按钮背景图像上,如示例9-8所示。

示例9-8:创建动态按钮。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?php
$font='../../../../Media/font/times';
$size =12;
$im=ImageCreateFromPNG('../../../../Media/Photo/image/1.png');
// 计算文本的位置。
$text =$_GET['text'];
$tsize = ImageTTFBBox($size,0,$font,$text);
$dx = abs($tsize[2]-$tsize[0]);
$dy = abs($tsize[5]-$tsize[3]);
$x = (ImageSx($im)-$dx)/2;
$y = (ImageSy($im)-$dy)/2+$dy;
// 绘制文本。
$black=ImageColorAllocate($im,0,0,0);
ImageTTFText($im,$size,0,$x,$y,$black,$font,$text);
header('Content-Type:image/png');
ImagePNG($im);
?>
  • 例9-8中的脚本可以在页面中这样调用:
1
<img src="button.php?text=PHP+Button">
  • URL中的符号"+”表示一个空格,因为空格在URL中是非法的,所以必须被编码成+,你可以使用PHP函数urlencode()来对按钮上的字符串进行编程,例如:
1
<img src="button.php?text=<?php echo urlencode('PHP Button')?">

缓存动态创建的按钮

  • 动态创建图像通常比发送静态图像慢一些,当使用相同的文本做参数时,得到的按钮往往是相同的,所以可用一个简单的缓存机制来使之显示的速度加快。
  • 示例9-9只在找不到缓存文件时,才会动态创建按钮,变量$path是一个目录,该目录对于Web服务器用户可写,按钮可以缓存到该目录下,filesize()函数返回一个文件的大小,readfile()函数把一个文件发送到浏览器,由于以下代码将表单参数中的文本作为文件名,所以是很不安全的。

示例9-9:缓存动态按钮。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<?php
header('Content-Type:image/png');
$path = "./tmp";// 按钮缓存路径。
$text = $_GET['text'];

if ($bytes = @filesize("$path/$text.png")){
// 发送缓存的图像。
header("Content-Length:$bytes");
readfile("$path/$text.png");
}else{
$font = '../../../../Media/font/times';
$size = 12;
$im = ImageCreateFromPNG('../../../../Media/Photo/image/1.png');
// 计算文本的位置。
$tsize = ImageTTFBBox($size, 0, $font, $text);
$dx = abs($tsize[2] - $tsize[0]);
$dy = abs($tsize[5] - $tsize[3]);
$x = (ImageSx($im) - $dx) / 2;
$y = (ImageSy($im) - $dy) / 2 + $dy;
// 绘制文本。
$black = ImageColorAllocate($im, 0, 0, 0);
ImageTTFText($im, $size, 0, $x, $y, $black, $font, $text);
header('Content-Type:image/png');
ImagePNG($im);
ImagePNG($im,"$path/$text.png");
}
?>

一个更快的缓存

  • 示例9-9还不够快,如果已经创建了图像,我们可以用一种更高级的机制,可以使对图像的请求完全不用和PHP打交道。
  • 首先,在你的Web服务器的根目录(Document Root)下创建一个buttons目录,确保Web服务器用户拥有写该目录的权限,例如,如果Document目录是/var/www/html,则创建/var/www/html/buttons目录。
  • 接着,编辑你的Apache httpd.conf文件,在其中加入以下内容:
1
2
3
<Location /buttons/>
ErrorDocument 404 /button.php
</Location>

示例9-10:更高效地缓存动态按钮。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
<?php
// 插入重定向的URL参数(如果有的话)
parse_str($_SERVER['REDIRECT_QUERY_STRING']);

$button_dir = '/buttons/';
$url = $_SERVER['REDIRECT_URL'];
$root = $_SERVER['DOCUMENT_ROOT'];

// 获得扩展名。
$ext = substr($url,strrpos($url,'.'));

// 从$url字符串中移除目录和扩展名。
$file = substr($url,strlen($button_dir),strlen($ext));

// 从安全考虑,不允许文件中出现'..'
$file = str_replace('..','',$file);

// 按钮上显示的文本。
$text = urldecode($file);

// 创建图像。
if (!isset($font)) $font='../../../../Media/font/times';
if (!isset($size)) $size =12;
$im = ImageCreateFromPNG('../../../../Media/Photo/image/1.png');
$tsize = ImageTTFBBox($size, 0, $font, $text);
$dx = abs($tsize[2] - $tsize[0]);
$dy = abs($tsize[5] - $tsize[3]);
$x = (ImageSx($im) - $dx) / 2;
$y = (ImageSy($im) - $dy) / 2 + $dy;
$black = ImageColorAllocate($im, 0, 0, 0);

// 发送和保存图像。
ImageTTFText($im, $size, 0, $x, $y, $black, $font, $text);
header('Content-Type:image/png');
ImagePNG($im);
ImagePNG($im,$root.$button_dir."$file.png");
ImageDestroy($im);
?>
  • 示例9-9中所用的技术的唯一不足是,按钮上的文字不能包含任何在文件名中非法的字符,但尽管如此,这还是缓存动态创建的图像的最高效的方法,如果你改变了按钮的外观并且需要重新创建缓存图像,只需删除buttons目录下的所有图像,下次它们就会在被请求时自动重新创建。
  • 你也可以更近一步,让你的button.php脚本支持多种类型的图像格式,只要检查$ext变量的值,然后调用相应的ImagePNG(),ImagrJPEG()ImageGIF()函数来创建图像,你也可以通过解析文件名,添加颜色,字号和字体之类的参数,甚至可以在URL中传递它们,由于例子中调用了parse_str()函数,类似http://your.site/buttons/php.png?size=16这样的URL将会以16号大小的字体在按钮上显示文字"php”

本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!