Outer-glow effect with PHP and the GD library
I was recently working on a photo gallery project for a friend who is an avid Flickr user. She had an established workflow when it came to making her work available to her friends and clients on Flickr and didn't want to change that workflow if she didn't have to.
Ok, now it's time to skip ahead. I built the side using the Flickr API, and everything is working swimmingly. I decided to hire my friend Matthew Armendariz to handle the interface design. Since the client was a friend of mine, having someone else be responsible for the creative would keep me free from having to worry about that process, and Matt is a pretty good designer.
It took no time for Matt to whip up a few comps, the one we ended up going with had a slight outer-glow around each photograph, and since we were working with seemingly fixed output from Flickr, I figured, no worries, I'll just create two "glowing" background images, and display one or the other depending on whether the current photo was portrait or landscape.
It worked like a charm... until I came across a few photographs that the client had uploaded with non-standard aspect ratios. Then I had the realization that these outer glows needed to be dynamically generated. Since as the developer there wasn't any way that I could trust that she upload files of any specific aspect ratio, and since she was using Flickr to manage her photos I couldn't (and wouldn't want to anyway) enforce any specific sizes uploaded, I needed to come up with a an easy, browser agnostic, and friendly solution.
CSS wasn't going to help me. SVG and Canvas isn't broadly enough supported. And since this site was pretty much Javascript free, I had to look to the server to help me execute the agreed upon creative work
Oh my GD!
The GD library is an often overlooked alternative to ImageMagick, but since it's light weight, comes with most PHP installs, and was already available on the production server, it seemed like the best choice.
First I had to start with making sure that the file I was generating was going to identify itself properly
Next was to pull in the parameters i was going to need to generate the correct size image... I decided to go with a 22px "border", which is really just the size of the glow.
-
$border = ($_REQUEST['b'])? $_REQUEST['b'] : 22;
-
$width = ($_REQUEST['w']) ? $_REQUEST['w']+($border*2): 500;
Next we create the image, using the specified or default dimensions. And then define the colors (in RGB) that will be used to generate the image... white and light gray.
-
$im = @imagecreatetruecolor($width, $height)
-
$white = imagecolorallocate($im, 255, 255, 255);
-
$gray= imagecolorallocate($im,200,200,200);
Now it's time to create our initial shape... First the image is painted entirely white, and then a box is drawn inside of the white image with the gray color.
-
imagefill($im, 0, 0, $white);
-
imagefilledrectangle($im, $border, $border, $width-$border, $height-$border,$gray);
Now there's just a grey box with a white border... not only is it boring, but it's not glowing at all. It's time to fix this. GD has a few decent filters built in, just as any image library should, and the ones that I chose to use for this were IMG_FILTER_SMOOTH and IMG_FILTER_GAUSSIAN_BLUR. The gaussian blur filter, unlike the one you find in PhotoShop, does not unfortunately accept parameters, so instead I had to put calls to GD's imagefilter() method in a for loop. The loop allowed me to also easily play around with the number of times and in what order each filter was applied to the image without having to do too much cutting and pasting.
-
for($i = 0; $i <10; $i++){
-
imagefilter($im,IMG_FILTER_SMOOTH, 0);
-
imagefilter($im,IMG_FILTER_GAUSSIAN_BLUR);
-
imagefilter($im,IMG_FILTER_GAUSSIAN_BLUR);
-
}
Now we just generate the image as a png, and then clear the memory
-
imagepng($im);
-
imagedestroy($im);
And that's all there is too it. Since the default size specified is 500px square, the default output looks like this. If I need to generate an outer–glow for an image that's 250px tall by 400px wide, I add the following query to the URI of the file blur.php?h=250&w=400 and voila! Of course caching the output of this file on the server will speed up any requests after the initial one, but that is beyond the scope of this post.
I've included the source of the file below.
-
<?php
-
$border = ($_REQUEST['b'])? $_REQUEST['b'] : 22;
-
$width = ($_REQUEST['w']) ? $_REQUEST['w']+($border*2): 500;
-
$im = @imagecreatetruecolor($width, $height)
-
$white = imagecolorallocate($im, 255, 255, 255);
-
$gray= imagecolorallocate($im,200,200,200);
-
imagefill($im, 0, 0, $white);
-
imagefilledrectangle($im, $border, $border, $width-$border, $height-$border,$gray);
-
for($i = 0; $i <10; $i++){
-
imagefilter($im,IMG_FILTER_SMOOTH, 0);
-
imagefilter($im,IMG_FILTER_GAUSSIAN_BLUR);
-
imagefilter($im,IMG_FILTER_GAUSSIAN_BLUR);
-
}
-
imagepng($im);
-
imagedestroy($im);
-
?>