Ashley Sheridan​.co.uk

PHP Image Header

Posted on

Despite efforts made by many groups to allow designers to embed fonts into their web pages, such as WEFT and CSS, no method has managed to achieve support across all the popular browsers. Currently, the CSS method looks the best bet, but is still too far in the distant future to be considered a viable option at the moment. Because of this, alternatives such as the Flash sIFR, but this relies on Flash to work, and introduces an overhead on the client-side. The only other option is to use images, which has been the standard method since day one. This has always been fine while you knew in advance all the images you requireed for headings, but when you wanted your site to become dynamic, you either had to use sIFR and hope your users all had Flash installed (so that means no hardly any mobile phone users, not even iPhones.)

There is an alternative in the form of server-side scripts which can dynamically produce the required heading graphics, in any font you choose. The script here is capable of producing multi-line images, in the font of your choice (although you will need to upload the font file with the script), as well as allowing you to set a couple of other various settings. Feel free to tweak this to your specific needs. Note, you will need to have GD installed, but most hosting will already have this installed.

<?php $text = (isset($_REQUEST['text']))?$_REQUEST['text']:'this is an example string'; $margin = (isset($_REQUEST['margin']))?$_REQUEST['margin']:5; $foreground = (isset($_REQUEST['foreground']))?$_REQUEST['foreground']:'#000000'; $background = (isset($_REQUEST['background']))?$_REQUEST['background']:'#ffffff'; $font = (isset($_REQUEST['font']))?$_REQUEST['font']:'arial.ttf'; $fontSize = (isset($_REQUEST['fontSize']))?$_REQUEST['fontSize']:12; $widthLimit = (isset($_REQUEST['width']))?$_REQUEST['width'] + 2 * $margin:170 + 2 * $margin; $file = (isset($_REQUEST['file']))?$_REQUEST['file']:'test.png'; $temp = imagettfbbox($fontSize, 0, $font, $text); $lineHeight = $temp[1] - $temp[7]; $words = explode(' ', $text); $wordLength = Array(); for($i=0; $i<count($words); $i++) { $temp = imagettfbbox($fontSize, 0, $font, $words[$i] . ' '); $wordLength[$words[$i]] = $temp[2] - $temp[0] + 2 * $margin; } $lineTotal = 0; $currentLine = 0; $line = Array(); $width = 0; // width to be used by the image $line[0] = ''; // just sets the first element of the array to prevent errors foreach($wordLength as $key => $value) { if(($lineTotal + $value) <= ($widthLimit - 2 * $margin)) { $lineTotal += $value; $line[$currentLine] .= $key . ' '; if($lineTotal > $width) { $width = $lineTotal; } } else { $lineTotal = $value; $currentLine ++; $line[$currentLine] = $key . ' '; if($lineTotal > $width) { $width = $lineTotal; } } } // create image $height = ($temp[1] - $temp[7] + $margin) * count($line); $img = imagecreatetruecolor($width, $height); $fore = imagecolorallocate($img, hexdec(substr($foreground, 1, 2)), hexdec(substr($foreground, 3, 2)), hexdec(substr($foreground, 5, 2))); $back = imagecolorallocate($img, hexdec(substr($background, 1, 2)), hexdec(substr($background, 3, 2)), hexdec(substr($background, 5, 2))); imagefill($img, 0, 0, $back); $count = 0; for($i=0; $i<count($line); $i++) { imagettftext($img, $fontSize, 0, $margin, (($i + 1) * $lineHeight + $margin), $fore, $font, $line[$i]); } imagepng($img, $file); ?>

Lines 2 through 9 handle capturing any GET or POST variables, and sets default values for any which have not been specified. Lines 11 & 12 just get the line height for the text.

Lines 14 to 20 creates an associative array of words and their computed image lengths. The lengths have a space character added, to allow for the extra space that is required between words. Lines 22 through 26 set up some variables for creating the final image. Of particular interest is the $line array, which is used to store the final lines of text for the image.

The real work is handled in the foreach loop at line 28. This iterates the individual words, adding each to the current line of text only while the total width for that line is less than, or equal to, the threshold limit specified in the $widthLimit variable. Throughout the iteration of this loop, the maximum width is found, which is used for the final image width, to avoid unecessary blank image space.

Finally, the image is created and each line of text is output, using the $file variable to determine the filename. Note that the images are all created in the same directory as the PHP file. If this needs to be different, either a relative path such as ../images/headings/ can be added to line 64 just before the filename using the . string concatenator, or you can specify a more full URL (either absolute, or relative to the PHP file), allowing for more precision of each heading image.

There are several things to note with this script. First, if the site is for anything other than personal use, i.e. a commercial site, then you may need to ensure you have the necessary permission to use the font you want. Also, this script is really only intended for headings, not paragraph text, as GD can use large amounts of memory, and you don't really want to have users downloading your entire site as one big image.

The script can accept the following parameters:

ParameterValues
$text Accepts a standard string. Characters which are not avialable in your chosen font will not be displayed.
$margin An integer value which determines the margin around the text block, and the distance between lines of text.
$foreground A 6 digit hex value (with preceeding #.)
$background A 6 digit hex value (with preceeding #.)
$font The URL to the font file you wish to use. This can be absolute or relative.
$fontSize The point size to be used by the font. A point is 1/72th of an inch.
$widthLimit The maximum width for the image heading, which determines where the word breaks occur.
$file The URL of the image file; can be absolute or relative. Linux hosting will require the correct write permissions to be set on the directory you specify for the image.