| abstract |  |
This is an example of using Gd / FreeType to generate image text labels with TTF font. Provided script could be used as "text rasterization service" to generate arbitrarily text-images for a web site. MD5-based authorization is used to avoid image generation by unauthorized users. | compatible |  |
- PHP 5 or higher
- PHP 4.1 or higher
- Gd 2.x, FreeType support in PHP
Our "text rasterization service" does the following:
- Receives text generation parameters(text and font-size) and md5 sign of secret key + parameters.
- Checks(by md5 sign) if rasterized text image exists in cache directory. If so, sends it to web browser and quits.
- Checks md5 authorization: computes md5 of secret key + parameters. If computed md5-sign equals to provided md5-sign,
then request is valid. Otherwise — somebody else is trying to use our "text rasterization service".
- Generates text image with imagettftext. Image size
exactly matches text size (using imagettfbbox)
- Sends generated image to browser
So, it is possible to automatically generate a lot of image text labels for a whole web site. Caching technique will decrease server load: images would be generated only once. <?php
// Checking for gd and Freetype support if (!function_exists('gd_info')) die('No <a href="http://ua.php.net/manual/en/ref.image.php">gd</a> support in PHP.');
$gd = gd_info(); if ($gd["FreeType Support"] == false) die('No FreeType support in gd</a>');
// If you're sure about gd & freetype support // -- comment out this block
// directory for caching generated images // should be writable $cache_dir = '/homa/anyexample/cache'; // DO NOT FORGET TO CHANGE
// testing cache dir // remove these lines if you're sure // that your cache dir is really writable to PHP scripts $tf = $cache_dir.'/'.md5(rand()).".test"; $f = @fopen($tf, "w"); if ($f == false) die("Fatal error! {$cache_dir} is not writable. Set 'chmod 777 {$cache_dir}' or something like this"); fclose($f); unlink($tf); // testing cache dir END
// full path to preferred TTF font // you could change this to be HTTP parameter $font = '/home/anyexample/FuturaBook.ttf'; // DO NOT FORGET TO CHANGE
// md5 secret $md5_secret_key = 'changeme'; // DO NOT FORGET TO CHANGE
// md5 sign of parameters $auth_sign = isset($_GET['a'])?$_GET['a']:'';
// checking for cached file: $cache_file = $cache_dir.'/'.$auth_sign.'.png';
if (file_exists($cache_file)) { // if cached file exists // output it and quit header("Content-type: image/png"); readfile($cache_file); exit(); }
// no cached file exists
// input parameters: text and size $text = isset($_GET['text'])?$_GET['text']:'default';
$font_size = isset($_GET['size'])?intval($_GET['size']):30; if ($font_size == 0) $font_size = 30; //
// basic sign checking: $computed_sign = md5($md5_secret_key.$text.$font_size); // computing md5 sum of concatenation // of secret key and parameters
// hmac-based alrorithm would fit this case more // but for real-world purpose md5 of concatenation // is enought
if ($computed_sign != $auth_sign) die('Auth failed'); // auth error, provided sign is invalid
// getting bounding box $bbox = imagettfbbox($font_size, 0, $font, $text); // imagettfbbox returns very strange results // so transforming them to plain width and height
$size_w = abs($bbox[2] - $bbox[0]); // width: right corner X - left corner X
$size_h = abs($bbox[7] - $bbox[1]); // height: top Y - bottom Y
// This is a lower-left corner // but imagettfbbox() sets (0,0) point // inside bounding box // so we shifting lower-left corner $x = -abs($bbox[0]); $y = $size_h - abs($bbox[1]);
$im = imagecreatetruecolor($size_w, $size_h); // creating image
$back = imagecolorallocate($im, 255, 255, 255); // background color $fore = imagecolorallocate($im, 0, 0, 0); // foreground color
imagefilledrectangle($im, 0, 0, $size_w - 1, $size_h - 1, $back); // filling with background color
imagettftext($im, $font_size, 0, $x, $y, $fore, $font, $text); // rendering text
imagepng($im, $cache_file); // outputing PNG image to file cache
imagedestroy($im); // destroy image
// sending data from cache file header("Content-type: image/png"); readfile($cache_file); ?>
To generate image 'Hello World', 90 pixels size you should call this script as (assuming you've saved it as font.php):
<img src="./font.php?text=Hello+World&size=90&a=4c9a240e98490275d845c96fdb8e5a19">
Note parameter 'a=4c9a240e98490275d845c96fdb8e5a19'. '4c9a240e98490275d845c96fdb8e5a19' is a result of md5('changemeHello World90'): concatenation of
secret key, text and font size.
You could use some helper function to set script arguments, like 'image_params':
<?php $md5_secret_key = 'changeme';
// returns parameters and md5 sign for // text generating service function img_params($text, $size) { global $md5_secret_key; $p = '?text='.urlencode($text).'&size='.$size.'&a='; return $p.md5($md5_secret_key.$text.$size); } ?>
<html><head><title>Font test</title></head> <body>
<center> <img src="./font.php<?php echo img_params('Hello World', 90);?>"> <br><br> <img src="./font.php<?php echo img_params('Enjoy the font generating service script from', 30); ?>"> <br><br> <a href="http://www.anyexample.com/"> <img src="./font.php<?php echo img_params('AnyExample', 100); ?>"> </a> </center>
</body> </html> See generated page. | warning |  |
- 'If-Modified-Since' and HTTP 304-based browser-caching is not used. You could implement it as in this example.
| tested by AnyExample.com
on 2007-06-19 |  |
- FreeBSD 6.2 :: PHP 5.2.1
- RHEL 5.0 :: PHP 4.4.5
| |
|