I have been asked numerous times in the past how I create this effect in some forum signatures so now I am releasing the code so you can see. It could equally be used as a background image in CSS (like the photo of the excavator above) so you could have a circulating series of background or in this case header images. I am sure you can think of many other neat uses for this script.

Demo rar’d archive (includes demo ‘Disgraceful Alfa’ gallery images) can be found at the end of the article.

  1. Extract into a new directory
  2. Open image.jpg in your favourite editor
  3. Change the BASE_DIR to reflect the absolute path to the directory containing the image.php file eg. /home/simon/flickering/
  4. chmod the storage.dat file to 777
  5. Then open the url in your browser….enjoy!

This is the PHP script (image.jpg is the file name):

<?php
/*
   Original script written by
   Simon Holywell (simonholywell.com)
   17/3/2006

   You may use this script for any purpose.  You can
   make changes to the code.  You may NOT redistribute
   the code, link back to my site.  All derivatives
   must be released and opensource.

   THIS NOTICE MUST ALWAYS APPEAR AT THE VERY TOP
   OF THE SCRIPT NO MATTER HOW MODIFIED IT IS.
*/

/*  Setup vars below
  ------------------------------------------ */
define('BASE_DIR', '/path/to/base/');  //base absolute path to this script
define('FILE_NAME', 'alfa'); //filename w/o the extension or number
define('IMAGE_PATH', BASE_DIR.'images/'.FILE_NAME); //where images are stored
define('FILE_SUFFIX', '.jpg'); //suffix (usually the extension of the images)
define('IMAGE_COUNT', 20); //number of images
define('DATA_FILE', BASE_DIR.'storage.dat'); //the file where the data is stored

/* File management
  ------------------------------------------ */
if(file_exists(DATA_FILE) && is_readable(DATA_FILE) && is_writable(DATA_FILE))
    $storage = fopen(DATA_FILE, "r+");
else
    $storage = @fopen(DATA_FILE, "w+");

if(!$storage) {
    print 'Error: You must make the data file readable (chmod 777) and it must exist!';
    exit();
}

// get the serialized array
$image_data = array();
$data = implode("", @file(DATA_FILE));
$image_data = unserialize($data);

// add one to move to the next image
if($image_data['position']++ >= IMAGE_COUNT)
    $image_data['position'] = 1;

// hit counter
$image_data['hit_counter']++;

// wipe files contents
@fseek($storage, 0); // move back to the beginning of the file
@ftruncate($storage, 0);  //leave 0 bytes in the file from this point

// stick the data back in the file
$data = serialize($image_data);
$data = @fputs($storage, $data);
@fclose($storage);

if(!$data){
    print 'Error: Could not write the data back to the file.  Please make sure that it exists and is chmod\'d to 777.';
    exit();
}

// verify the required image exists
if(!file_exists(IMAGE_PATH.$image_data['position'].FILE_SUFFIX)) {
    print 'Error: Image ('.IMAGE_PATH.$image_data['position'].FILE_SUFFIX.') cannot be found.  Please ensure that you have set the correct number of images and that image directory is readable.';
    exit();
}

// tell the user's browser that it is an image
header("Content-type: image/jpeg");

/* Image Manipulation
  ------------------------------------------ */
// load the image from your selection of images
$image = imagecreatefromjpeg(IMAGE_PATH.$image_data['position'].FILE_SUFFIX);
$size = getimagesize(IMAGE_PATH.$image_data['position'].FILE_SUFFIX); // Read the size

// allocate the text colours
$white = imagecolorallocate($image, 255, 255, 255);
$black = imagecolorallocate($image, 0, 0, 0);

// define the font, x position, y postition
$font = 2;
$x = 5;
$y = $size[1] - 17;  // equivalent to 17px from the base of the image

// write hit counter (shadow first and then the white)
imagestring($image, $font, $x + 2, $y + 2, 'Views: '.$image_data['hit_counter'], $black);
imagestring($image, $font, $x, $y, 'Views: '.$image_data['hit_counter'], $white);

// write the current position of the slideshow to the image
// obviously you will have to take more off of x if you have more
// than 100 images other wise the zero will be off "screen"
imagestring($image, $font, $size[0] - 50, $y + 2, $image_data['position'].' of '.IMAGE_COUNT, $black);
imagestring($image, $font, $size[0] - 52, $y, $image_data['position'].' of '.IMAGE_COUNT, $white);

/* Output image
  ------------------------------------------ */
imagejpeg($image);
imagedestroy($image);
?>

You also need to add a line to .htaccess:

ForceType application/x-httpd-php

Due to the change in the .htaccess file Apache now treats .jpg files as PHP in this directory. This then allows us to execute some php code which ultimately outputs a JPEG header and JPEG data, which shows up as an image when its linked to. The browser is none the wiser as it does not look like remote script invocation like some previous methods that have been released. So this can be used anywhere an image can without anyone knowing until they see it changing!

Flickering Images (zip file)