views:

300

answers:

5

I have a place holder image saying something like:

Your rating is:
   [rating here]

My PHP code is supposed to dynamically insert the rating number where there is a blank space left out for it on the placeholder image. How can I do that?

+1  A: 

I know that the question is "How to dynamically create an image with a specified number on it?" but I'll address the underlying problem instead. Dynamic image manipulation is heavy on the CPU. Just don't do it. And certainly don't do it in the context of a web request. Consider having static images instead and then show the correct one depending on the rating. Even if your rating system goes all the way to 100, it would be better to have 100 static images than to keep redrawing the same image over and over.

Al W
Actually it could be anywhere from 0.1 to 9.99, so I don't really want to do manually.
Click Upvote
The same image should't be generated twice - they should be stored and retrieved later if the same image is requested.
Kristian J.
+7  A: 

Here's a an example how you could do it - use gd function calls to make your image, but play nice and cache the images. This sample plays even nicer by ensuring that if the browser already has the required image, it returns a 304...

#here's where we'll store the cached images
$cachedir=$_SERVER['DOCUMENT_ROOT'].'/imgcache/'

#get the score and sanitize it
$score=$_GET['score'];
if (preg_match('/^[0-9]\.[0-9]{1,2}$/', $score)
{
    #figure out filename of cached file
    $file=$cachedir.'score'.$score.'gif'; 

    #regenerate cached image
    if (!file_exists($file))
    {
        #generate image - this is lifted straight from the php
        #manual, you'll need to work out how to make your
        #image, but this will get you started

        #load a background image
        $im     = imagecreatefrompng("images/button1.png");

        #allocate color for the text
        $orange = imagecolorallocate($im, 220, 210, 60);

        #attempt to centralise the text  
        $px     = (imagesx($im) - 7.5 * strlen($score)) / 2;
        imagestring($im, 3, $px, 9, $score, $orange);

        #save to cache
        imagegif($im, $file);
        imagedestroy($im);
    }

    #return image to browser, but return a 304 if they already have it
    $mtime=filemtime($file);

    $headers = apache_request_headers(); 
    if (isset($headers['If-Modified-Since']) && 
        (strtotime($headers['If-Modified-Since']) >= $mtime)) 
    {
        // Client's cache IS current, so we just respond '304 Not Modified'.
        header('Last-Modified: '.gmdate('D, d M Y H:i:s', $mtime).' GMT', true, 304);
        exit;
    }


    header('Content-Type:image/gif');
    header('Content-Length: '.filesize($file));
    header('Last-Modified: '.gmdate('D, d M Y H:i:s', $mtime).' GMT');
    readfile($file);


}
else
{
    header("HTTP/1.0 401 Invalid score requested");
}

If you put this in image.php, you would use as follows in an image tag

<img src="image.php?score=5.5" alt="5.5" />
Paul Dixon
+2  A: 

Use static images ranging from 0 to 9 and just combine them on the page to build large numbers:

Your Rating: [image1.jpg][image2.jpg][image3.jpg]

Gerhard
A: 

Also see alpha-blending example at http://ca3.php.net/manual/en/function.imagecopymerge.php#73477

Instead of using imagestring() to write with built-in or TTF fonts, you could create your own 0-9 characters as 24-bit PNG images with alpha-blending, then composite them in with imagecopymerge(). It's a bit more work, but would give you much more control over the look of the character-set.

Hugh Bothwell
A: 

Why not set the number as text in a div, then style it with font and background choices?

John Dunagan