Creating Image Banners using PHP Part 2

Posted by: JDS

I have modified and improved my original Image Banner script.

The newest version of this script allows for variable line heights, centered text, drop shadows, background images, and more.
Here is an example:

The script is included here on this page, below.

The original article is here.

Note: This script requires NetPBM and ImageMagick installed on the server for drop shadows to work.

header_image.php PHP Source

The following is the source for the image creation script.  To use it, call it in an HTML page like so:

<?php
// image_header.php
// Generate dynamic text banner images using TTF fonts and PHP.
// Copyright 2003,2004  The Johns Hopkins University, All rights reserved.
// Author:  Jeffrey D. Silverman
// Date:    14-January-2004
// Description:
// Use this script to generate graphic headers.
// Pass in a value for "$text" to print.
// Example usage:
//    <img src='header_image.php?text=this%20is%20the%20text' width='300' height='23'>
//
// CONFIGURATION - Change these items manually here or pass in values via the URL
// ITEMS that can be passed in (optionally) via the URL are:
// fontdir
// bg_b
// bgcolor
// bg_g
// bgimage
// bg_r
// center_x
// center_y
// cols
// drop_shadow
// fg_b
// fgcolor
// fg_g
// fg_r
// font
// fontdir
// image_height
// image_width
// lineheight
// linewidth
// shadow_offset_x
// shadow_offset_y
// text
// x
// y
define("fontdir", "." ); // Important! This MUST be a real directory for the script to work!
define("font",   "arial.ttf" ); // Important! This MUST be a real TTF or PostScript font file for the script to work!
define("TEMP_IMAGE_DIR",   "header_image_temp" );

define("image_width",   100 );
define("image_height",   23 );
define("lineheight",   12 );
define("x",   10 );
define("y",   lineheight );
define("cols",   1 );
// Text (foreground) color, RGB values 0-255
define("fg_r",   0 );
define("fg_g",   0 );
define("fg_b",   0 );
// Background color, RGB values 0-255
define("bg_r",   255 );
define("bg_g",   255 );
define("bg_b",   255 );

# Configuration of external programs
# You MUST put the full path to the proper programs here. Not doing so will disable
# the drop-shadow functionality
define("GDTOPNG", "/usr/local/bin/gdtopng");
define("MOGRIFY", "/usr/bin/mogrify");
// END OF CONFIGURATION

// DO NOT CHANGE BELOW THIS LINE //////////////////////////

if (! is_dir(TEMP_IMAGE_DIR) ) mkdir(TEMP_IMAGE_DIR);

// Check for saved images based on MD5 Hash of the $_SERVER['QUERY_STRING']
$saved_image = TEMP_IMAGE_DIR . "/" . md5($_SERVER['QUERY_STRING']) . ".png";
if (is_file( $saved_image)){
    header("Content-type: image/png");
    echo file_get_contents($saved_image);
    exit;
} else {
    $fontdir = $_REQUEST['fontdir'] ? $_REQUEST['fontdir'] : fontdir;
    $font = $_REQUEST['font'] ? $_REQUEST['font'] : font;
    $image_width = $_REQUEST['image_width'] ? $_REQUEST['image_width'] : image_width;
    $image_height = $_REQUEST['image_height'] ? $_REQUEST['image_height'] : image_height;
    $lineheight = $_REQUEST['lineheight'] ? $_REQUEST['lineheight'] : lineheight;
    $x = $_REQUEST['x'] ? $_REQUEST['x'] : x;
    // $y = $_REQUEST['y'] ? $_REQUEST['y'] : $_REQUEST['lineheight'] ? $_REQUEST['lineheight'] : lineheight;
    $y = $_REQUEST['y'] ? $_REQUEST['y'] : y;
    if ($_REQUEST['center_x']){
        // x-offset = ((width of box) - (width of string)) / 2
        $x = ( $image_width / 2 ) + ($image_height / 2 );
    }
    // Need to make this dynamic.  Not all header images should break on multiple lines! (Notably the page_title)
    if ($_REQUEST['linewidth']){
        // linewidth MUST be passed in through the URL to split long lines.
        // Otherwise the text will be all on one line.
        $split_lines = preg_split("/(.{" . $_REQUEST['linewidth'] . "}\S*)\s/", $_REQUEST['text'], -1, PREG_SPLIT_DELIM_CAPTURE);
    } else {
        $split_lines = array($_REQUEST['text']);
    }

    $cols = $_REQUEST['cols'] ? $_REQUEST['cols'] : cols;
    // Text color, RGB values 0-255
    $fg_r = $_REQUEST['fg_r'] ? $_REQUEST['fg_r'] : fg_r;
    $fg_g = $_REQUEST['fg_g'] ? $_REQUEST['fg_g'] : fg_g;
    $fg_b = $_REQUEST['fg_b'] ? $_REQUEST['fg_b'] : fg_b;
    // background color, RGB values 0-255
    $bg_r = $_REQUEST['bg_r'] ? $_REQUEST['bg_r'] : bg_r;
    $bg_g = $_REQUEST['bg_g'] ? $_REQUEST['bg_g'] : bg_g;
    $bg_b = $_REQUEST['bg_b'] ? $_REQUEST['bg_b'] : bg_b;
    // Background Image
    $fgcolor = $_REQUEST['fgcolor'] ? $_REQUEST['fgcolor'] : false;
    $bgcolor = $_REQUEST['bgcolor'] ? $_REQUEST['bgcolor'] : false;
    $bgimage = $_REQUEST['bgimage'] ? $_REQUEST['bgimage'] : false;
    // Sample colors...
    // $white = imagecolorallocate($im, 255, 255, 255);
    // $gray1 = imagecolorallocate($im, 204, 204, 204);
    // $white = imagecolorallocate($im, 255, 255, 255);
    // $orange = imagecolorallocate($im, 220, 210, 60);
    // $dark_red = imagecolorallocate($im, 130, 28, 28);
    // $black = imagecolorallocate($im, 0, 0, 0);

    $filetypes = array(
                        "gif" => "gif"
                      , "jpg" => "jpeg"
                      , "jpeg" => "jpeg"
                      , "jpe" => "jpeg"
                      , "png" => "png"
                      );

    // TO DEBUG. Set Content-tpye to text/plain
    // header("Content-type: text/html");
    header("Content-type: image/png");
    if ($fgcolor) {
        $fgcolor = preg_replace("/[^0-9A-Za-z]/", "", $fgcolor);
        list($fg_r, $fg_g, $fg_b) = array(hexdec( substr($fgcolor, 0, 2) ),
                hexdec( substr($fgcolor, 2, 2) ),
                hexdec( substr($fgcolor, 4, 2) ));
    }
    if ($bgcolor) {
        $bgcolor = preg_replace("/[^0-9A-Za-z]/", "", $bgcolor);
        list($bg_r, $bg_g, $bg_b) = array(hexdec( substr($bgcolor, 0, 2) ),
                hexdec( substr($bgcolor, 2, 2) ),
                hexdec( substr($bgcolor, 4, 2) ));
    }
    // Hack/Bugfix:
    $result = preg_replace("/&amp;/", "&", $_REQUEST['text']); // fixes problem with &amp; showing up inside images!

    foreach ($split_lines as $line){
        if (! preg_match("/^\s*$/", $line)) $lines[] = $line;
    }
    $no_lines = count($lines);
    if ($_REQUEST['center_y']){
        $center_offset = ($no_lines + 1);
        $y = ($image_height / 2 ) - ( (($no_lines / 2) * $lineheight) - $lineheight );
    }


    // $lines = preg_split("/\n/", $result);
    $result = preg_replace("/\n/", "\r\n", $result);
    $im = imagecreate($image_width, $image_height);
    $im_shadow = imagecreate($image_width, $image_height);

    if (is_file($bgimage)){
        $suffix = array_pop(split("\.", $bgimage));
        $func = "imagecreatefrom" . $filetypes[$suffix];
        $im2 = $func($bgimage);
        imagecopyresized($im, $im2, 0, 0, 0, 0, 1, 1, 1, 1);
    }


    $background = imagecolorallocate($im, $bg_r, $bg_g, $bg_b);
    $black = imagecolorallocate($im, 0, 0, 0);
    $textcolor = imagecolorallocate($im, $fg_r, $fg_g, $fg_b);

    if ($_REQUEST['drop_shadow'] == 1 and (defined("GDTOPNG") and defined("MOGRIFY"))){
        $y_orig = $y;
        $shadow_offset_x = isset($_REQUEST['shadow_offset_x']) ? $_REQUEST['shadow_offset_x'] : 2;
        $shadow_offset_y = isset($_REQUEST['shadow_offset_y']) ? $_REQUEST['shadow_offset_y'] : 2;
        foreach ($lines as $string) {
            $string = preg_replace("/^\s*/", "", $string);
            imagefttext($im, $lineheight - 1, 0, $x+$shadow_offset_x, $y+$shadow_offset_y, $black, "$fontdir/$font",  $string, array() );
            $y += $lineheight;
        }
        $y = $y_orig;
        $tempimage = md5(time() . "" . rand(0,10000000));

        imagegd($im, "/tmp/$tempimage.gd");
        system(GDTOPNG . " /tmp/$tempimage.gd /tmp/$tempimage.png");
        system(MOGRIFY . " -blur 2 /tmp/$tempimage.png");
        $im = imagecreatefrompng("/tmp/$tempimage.mgk");
        unlink("/tmp/$tempimage.png");
        unlink("/tmp/$tempimage.gd");
        unlink("/tmp/$tempimage.mgk");

        $textcolor = imagecolorallocate($im, $fg_r, $fg_g, $fg_b);
        foreach ($lines as $string) {
            $string = preg_replace("/^\s*/", "", $string);
            imagefttext($im, $lineheight - 1, 0, $x, $y, $textcolor, "$fontdir/$font",  $string, array() );
            $y += $lineheight;
        }
    } else {
        foreach ($lines as $string) {
            $string = preg_replace("/^\s*/", "", $string);
            imagefttext($im, $lineheight - 1, 0, $x, $y, $textcolor, "$fontdir/$font",  $string, array() );
            $y += $lineheight;
        }
    }
    imagepng($im);
    imagepng($im, $saved_image);
    imagedestroy($im);
}
?>
« Prev item - Next Item »
---------------------------------------------

Comments


Hello!

I copied and tested your image banner script but could not get it to work -no image appeared on the screen when I run it. I look forward to your reply. Thanks in advance.
In line 87 should be '-' instead of '+' to get centered text.
Everything I've tried works great except for the bgimage function.. it doesn't work passing it through the url or defining it in the script :( Any idea why this wouldn't work?

Leave comment