<?php
/*
    Dynamic Heading Generator
    By Stewart Rosenberger
    http://www.stewartspeak.com/headings/    

    This script generates PNG images of text, written in
    the font/size that you specify. These PNG images are passed
    back to the browser. Optionally, they can be cached for later use. 
    If a cached image is found, a new image will not be generated,
    and the existing copy will be sent to the browser.

    Additional documentation on PHP's image handling capabilities can
    be found at http://www.php.net/image/    
*/


$font_file  = 'ARIAL.TTF' ;
$font_size  = 12 ;
$font_color = '#000000' ;
$background_color = '#ffffff' ;
$transparent_background  = true ;
$cache_images = true ;
$cache_folder = 'cache' ;







/*
  ---------------------------------------------------------------------------
   For basic usage, you should not need to edit anything below this comment.
   If you need to further customize this script's abilities, make sure you
   are familiar with PHP and its image handling capabilities.
  ---------------------------------------------------------------------------
*/

$mime_type = 'image/png' ;
$extension = '.png' ;
$send_buffer_size = 4096 ;

// check for GD support
if(!function_exists('ImageCreate'))
    fatal_error('Error: Server does not support PHP image generation') ;

// clean up text
if(empty($_GET['text']))
    fatal_error('Error: No text specified.') ;
    
$text = $_GET['text'] ;
if(get_magic_quotes_gpc())
    $text = stripslashes($text) ;
$text = javascript_to_html($text) ;

// look for cached copy, send if it exists
$hash = md5(basename($font_file) . $font_size . $font_color .
            $background_color . $transparent_background . $text) ;
$cache_filename = $cache_folder . '/' . $hash . $extension ;
if($cache_images && ($file = @fopen($cache_filename,'rb')))
{
    header('Content-type: ' . $mime_type) ;
    while(!feof($file))
        print(($buffer = fread($file,$send_buffer_size))) ;
    fclose($file) ;
    exit ;
}

// check font availability
$font_found = is_readable($font_file) ;
if(!$font_found)
{
    fatal_error('Error: The server is missing the specified font.') ;
}

// create image
$background_rgb = hex_to_rgb($background_color) ;
$font_rgb = hex_to_rgb($font_color) ;
$dip = get_dip($font_file,$font_size) ;
$box = @ImageTTFBBox($font_size,0,$font_file,$text) ;
$image = @ImageCreate(abs($box[2]-$box[0]),abs($box[5]-$dip)) ;
/*if(!$image || !$box)
{
    fatal_error('Error: The server could not create this heading image.') ;
}*/

// allocate colors and draw text
$background_color = @ImageColorAllocate($image,$background_rgb['red'],
    $background_rgb['green'],$background_rgb['blue']) ;
$font_color = ImageColorAllocate($image,$font_rgb['red'],
    $font_rgb['green'],$font_rgb['blue']) ;   
ImageTTFText($image,$font_size,0,-$box[0],abs($box[5]-$box[3])-$box[1],
    $font_color,$font_file,$text) ;

// set transparency
if($transparent_background)
    ImageColorTransparent($image,$background_color) ;

header('Content-type: ' . $mime_type) ;
ImagePNG($image) ;

// save copy of image for cache
if($cache_images)
{
    @ImagePNG($image,$cache_filename) ;
}

ImageDestroy($image) ;
exit ;


/*
	try to determine the "dip" (pixels dropped below baseline) of this
	font for this size.
*/
function get_dip($font,$size)
{
	$test_chars = 'abcdefghijklmnopqrstuvwxyz' .
			      'ABCDEFGHIJKLMNOPQRSTUVWXYZ' .
				  '1234567890' .
				  '!@#$%^&*()\'"\\/;.,`~<>[]{}-+_-=' ;
	$box = @ImageTTFBBox($size,0,$font,$test_chars) ;
	return $box[3] ;
}


/*
    attempt to create an image containing the error message given. 
    if this works, the image is sent to the browser. if not, an error
    is logged, and passed back to the browser as a 500 code instead.
*/
function fatal_error($message)
{
    // send an image
    if(function_exists('ImageCreate'))
    {
        $width = ImageFontWidth(5) * strlen($message) + 10 ;
        $height = ImageFontHeight(5) + 10 ;
        if($image = ImageCreate($width,$height))
        {
            $background = ImageColorAllocate($image,255,255,255) ;
            $text_color = ImageColorAllocate($image,0,0,0) ;
            ImageString($image,5,5,5,$message,$text_color) ;    
            header('Content-type: image/png') ;
            ImagePNG($image) ;
            ImageDestroy($image) ;
            exit ;
        }
    }

    // send 500 code
    header("HTTP/1.0 500 Internal Server Error") ;
    print($message) ;
    exit ;
}


/* 
    decode an HTML hex-code into an array of R,G, and B values.
    accepts these formats: (case insensitive) #ffffff, ffffff, #fff, fff 
*/    
function hex_to_rgb($hex)
{
    // remove '#'
    if(substr($hex,0,1) == '#')
        $hex = substr($hex,1) ;

    // expand short form ('fff') color
    if(strlen($hex) == 3)
    {
        $hex = substr($hex,0,1) . substr($hex,0,1) .
               substr($hex,1,1) . substr($hex,1,1) .
               substr($hex,2,1) . substr($hex,2,1) ;
    }

    if(strlen($hex) != 6)
        fatal_error('Error: Invalid color "'.$hex.'"') ;

    // convert
    $rgb['red'] = hexdec(substr($hex,0,2)) ;
    $rgb['green'] = hexdec(substr($hex,2,2)) ;
    $rgb['blue'] = hexdec(substr($hex,4,2)) ;

    return $rgb ;
}


/*
    convert embedded, javascript unicode characters into embedded HTML
    entities. (e.g. '%u2018' => '&#8216;'). returns the converted string.
*/
function javascript_to_html($text)
{
    $matches = null ;
    preg_match_all('/%u([0-9A-F]{4})/i',$text,$matches) ;
    if(!empty($matches)) for($i=0;$i<sizeof($matches[0]);$i++)
        $text = str_replace($matches[0][$i],
                            '&#'.hexdec($matches[1][$i]).';',$text) ;

    return $text ;
}

?>

That's my code. I get these errors:

Warning: imagecolorallocate(): supplied argument is not a valid Image resource in /var/www/ripgm/images/email.php on line 92

Warning: imagettftext() expects parameter 1 to be resource, boolean given in /var/www/ripgm/images/email.php on line 94

Warning: imagecolortransparent(): supplied argument is not a valid Image resource in /var/www/ripgm/images/email.php on line 98

Warning: Cannot modify header information - headers already sent by (output started at /var/www/ripgm/images/email.php:92) in /var/www/ripgm/images/email.php on line 100

Warning: imagepng(): supplied argument is not a valid Image resource in /var/www/ripgm/images/email.php on line 101

Warning: imagedestroy(): supplied argument is not a valid Image resource in /var/www/ripgm/images/email.php on line 109

Can anyone see any issues here?

Try replacing line 82 in your script with the following:

$image = imagecreate(abs($box[2]-$box[0]),abs($box[5]-$dip));

I believe the @ symbol was messing with your code.

I appreciate the help. This seems to have caused an extra error. Here's what I get when I change it to that.

Warning: imagecreate() [function.imagecreate]: Invalid image dimensions in /var/www/ripgm/images/email.php on line 82

Warning: imagecolorallocate(): supplied argument is not a valid Image resource in /var/www/ripgm/images/email.php on line 92

Warning: imagettftext() expects parameter 1 to be resource, boolean given in /var/www/ripgm/images/email.php on line 94

Warning: imagecolortransparent(): supplied argument is not a valid Image resource in /var/www/ripgm/images/email.php on line 98

Warning: Cannot modify header information - headers already sent by (output started at /var/www/ripgm/images/email.php:82) in /var/www/ripgm/images/email.php on line 100

Warning: imagepng(): supplied argument is not a valid Image resource in /var/www/ripgm/images/email.php on line 101

Warning: imagedestroy(): supplied argument is not a valid Image resource in /var/www/ripgm/images/email.php on line 109

Well for one, why are you using a heading generating script to generate an image when it uses web-safe font?

I'm just trying to convert email addresses into images. I guess I'm going about it all wrong. Can someone point me in the correct direction?

I found this tutorial, and I follow it, but then it tells me it can't create the image because there are errors. Here's the code i have now:

<?php
header('Content-type: image/png');
$text = $_GET['text'];
$im = imagecreatefrompng ("email.png");
$color = imagecolorallocate($im, 0, 0, 0);
$font = 'ARIAL.TTF';
$fontsize = 12;
$size = imagettfbbox($fontsize, 0, $font, $text); //calculate the pixel of the string
$dx = (imagesx($im)) - (abs($size[2]-$size[0])) - 20; //calculate the location to start the text
imagettftext($im, $fontsize, 0, $dx, 13, $color, $font, $text);
imagepng($im);
imagedestroy($im);
?>

Alright, I figured it out. The path to my font file was incorrect.

This article has been dead for over six months. Start a new discussion instead.