Automated Image Reflect Effect

Friday 30th July, 2010

I'm not a huge fan of the 'shiny surface' image effect that has become so prolific over the last few years - and to be honest its probably the very fact that it has become so prolific that makes me cautious over using it.

That said the effect can be nice if used sparingly. And sometimes clients are dead set on using it... So how do you let them use it without having to compromise a CMS (i.e. not having to reply on the user to create the image reflection effect themselves which would certainly result in dozens of different variations across the site).

The answer is PHP's GD library. Simply take an image, run it through a couple of functions and have a shiny new one come out the other side.

Simply save the following code in a PHP file somewhere on your server then when you want an image to be given the shiny surface treatment simply link to this file with a query string including the link to the original file (with slashes replaced with double underscores to avoid any dodgy server setups).

<?
// Function to create the gradient effect
function verticalGradient($image,$startColor,$endColor) {
    // get image width and height
    global $width;
    global $height;
    
    // get colours
    $r=($endColor >> 16) & 0xFF;
    $g=($endColor >> 8) & 0xFF;
    $b=($endColor) & 0xFF;
    
    // apply a blur filter to the image
    imagefilter($image, IMG_FILTER_GAUSSIAN_BLUR);
    
    // copy image into background
    $background=imagecolorallocate($image,$r,$g,$b);
    imagefill($image,0,0,$background);
    
    // loop through the image
    // alter the alpha variable to adjust how quickly the image fades - the lower the number the slower it fades
    if ($height>0) {
        $alpha = 3;
        $r=($startColor >> 16) & 0xFF;
        $g=($startColor >> 8) & 0xFF;
        $b=($startColor) & 0xFF;
        for ($t=0; $t<50; $t++) {
            imageline($image, 0, $t, $width, $t, imagecolorallocatealpha($image,$r,$g,$b,127-($t*$alpha)));
        }
    }
}

// choose your colours (hexadecimal values)
$endColor    = 0;
$startColor = 0xFFFFFF;
 
// output the page as an image
header("Content-type: image/png");
 
// get the image location from the query string, if it doesnt exist exit
// replace the double underscores with slashes
if (isset($_GET['src'])) {
    $filePath = str_replace("__", "/", $_GET['src']);
} else {
    exit();
}
// get the file extension and create a new image
$ext = strtolower(substr(strrchr($filePath, "."), 1));
switch ($ext) {
    case 'jpg':
        $image = imagecreatefromjpeg($filePath);
        break;
    case 'gif':
        $image = imagecreatefromgif($filePath);
        break;
    case 'png':
        $image = imagecreatefrompng($filePath);
        break;
}

// get the image width and height
$width  = imagesx($image);
$height = imagesy($image);
 
// create two new 'intermediate' images
$graid   = imagecreatetruecolor($width, 64);
$final  = imagecreatetruecolor($width, $height+36);

// work out how many repetitions need to be done when redrawing the image
$reps = ($height > $width)?$height:$width;

// rotate original image 180 degrees
$rotated = imagerotate($image, 180, 0);

// flip rotated image to produce mirror
for($i=0;$i<$reps;$i++){
    imagecopy($graid, $rotated, ($width - $i - 1), 0, $i, 0, 1, $height);
}

// add gradient to part of image
verticalGradient($graid,$startColor,$endColor);

// combine the original image and the gradient on to a new canvas
for($i=0;$i<$reps;$i++){
    imagecopy($final, $graid, $i, ($height-7), $i, 0, 1, $height);
}
for($i=0;$i<$reps;$i++){
    imagecopy($final, $image, $i, 0, $i, 0, 1, $height);
}
imagepng($final);
imagedestroy($image);
imagedestroy($graid);
imagedestroy($final);
?>

back