Archive for June, 2008

not at the speed of (spot) light

not at the speed of (spot) light
not at the speed of (spot) light, originally uploaded by naterkane.

Spotlight seems to want to take it’s sweet time. In a little over 21.5
days, the contents of my computer should be indexed apparently.

The new guard for my back door

The new guard for my back door
The new guard for my back door, originally uploaded by naterkane.

My friend Chris Stain just came by and put this guy on the door to my
garage. This is one tough looking kid.

Coney Island boardwalk

Coney Island boardwalk
Coney Island boardwalk, originally uploaded by naterkane.

I took a bike ride down to coney island for the mermaid parade. And
this was the only photo I took.

Grand Army Plaza

Grand Army Plaza
Grand Army Plaza, originally uploaded by naterkane.

My tree enjoys such a lovely day

My tree enjoys such a lovely day
My tree enjoys such a lovely day, originally uploaded by naterkane.

My little mouser

My little mouser
My little mouser, originally uploaded by naterkane.

Nadia and Diddy Dat caught a prize today

Webmonkey party

Webmonkey party
Webmonkey party, originally uploaded by naterkane.

Best,
Nater Kane

Ice cubes

Ice cubes
Ice cubes, originally uploaded by naterkane.

Both funny, and a choking hazard.

Back home at the ottobar

Back home at the ottobar
Back home at the ottobar, originally uploaded by naterkane.

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

PHP:
  1. header ("Content-type: image/png");

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.

PHP:
  1. $border = ($_REQUEST['b'])? $_REQUEST['b'] : 22;
  2. $width = ($_REQUEST['w']) ? $_REQUEST['w']+($border*2): 500;
  3. $height = (isset($_REQUEST['h'])) ? $_REQUEST['h']+($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.

PHP:
  1. $im = @imagecreatetruecolor($width, $height)
  2.       or die("Cannot Initialize new GD image stream");
  3. $white = imagecolorallocate($im, 255, 255, 255);
  4. $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.

PHP:
  1. imagefill($im, 0, 0, $white);
  2. 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.

PHP:
  1. for($i = 0; $i <10; $i++){
  2.     imagefilter($im,IMG_FILTER_SMOOTH, 0);
  3.     imagefilter($im,IMG_FILTER_GAUSSIAN_BLUR);
  4.     imagefilter($im,IMG_FILTER_GAUSSIAN_BLUR);
  5. }

Now we just generate the image as a png, and then clear the memory

PHP:
  1. imagepng($im);
  2. 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:
  1. <?php
  2. header ("Content-type: image/png");
  3. $border = ($_REQUEST['b'])? $_REQUEST['b'] : 22;
  4. $width = ($_REQUEST['w']) ? $_REQUEST['w']+($border*2): 500;
  5. $height = (isset($_REQUEST['h'])) ? $_REQUEST['h']+($border*2): 500;
  6. $im = @imagecreatetruecolor($width, $height)
  7.       or die("Cannot Initialize new GD image stream");
  8. $white = imagecolorallocate($im, 255, 255, 255);
  9. $gray= imagecolorallocate($im,200,200,200);
  10. imagefill($im, 0, 0, $white);
  11. imagefilledrectangle($im, $border, $border, $width-$border, $height-$border,$gray);
  12. for($i = 0; $i <10; $i++){
  13.     imagefilter($im,IMG_FILTER_SMOOTH, 0);
  14.     imagefilter($im,IMG_FILTER_GAUSSIAN_BLUR);
  15.     imagefilter($im,IMG_FILTER_GAUSSIAN_BLUR);
  16. }
  17. imagepng($im);
  18. imagedestroy($im);
  19. ?>


Nater Kane naterkane personal http://www.naterkane.com LinkedIn Profile Web Technologist personal nater@naterkane.com 1978-09-12 voice 845.234.6698 | fax 707.922.0593
964 Flushing Ave. Brooklyn, NY 11206