Manipulating images in PHP isn’t all that difficult. WordPress offers some functions to make it easier, and integrating with the WordPress uploader isn’t at all difficult, really.

For example, let’s say your theme needed a black and white version of the images, sized at 100×100, and cropped to that size. This might be suitable for Next/Previous images to use for a gallery, perhaps…

This simple function hooks into the after_setup_theme hook, which is loaded after the theme’s functions.php file is loaded. The function calls add_image_size to add a new image size for the uploader to create for each image that is uploaded into the WordPress media library. The size is specified as 100×100 with hard cropping.

Now that is easy enough, but we need to make the image black and white. To do this, we’ll hook into the wp_generate_attachment_metadata filter. This filter is called after the images have been resized and saved, but before the metadata about those resized images has been added to the attachment post. We’re not actually using this filter as a “filter”, but we need some of the meta data so this is as good a place to hook as any, as long as we remember to return the metadata again.

This bit of code gets our upload directory path, makes sure it’s trailing slashed, then appends the filename of our themename-bw-image file to it. Thus, after this is run, $file contains the full local path to the image we want to make black and white.

list($orig_w, $orig_h, $orig_type) = @getimagesize($file);

This line of code simply gets the image size and type into some variables. We really only need the type for later, but this is an easy way to do it.

$image = wp_load_image($file);

The wp_load_image function is a handy one. It reads in the image and returns a PHP image resource for us to work with.

imagefilter($image, IMG_FILTER_GRAYSCALE);

This simply applies the grayscale filter to the image resource, making it black and white.

Finally, we save the image back to the same file, overwriting the color one with the black and white one.

return $meta;

Since we used a filter, it’s important that we don’t leave out the final return to return the original information we were passed in, so that the metadata gets properly stored in the attachment post. We didn’t actually modify the metadata here, though we could.