@otto42 Did I hear you right that there’s greyscale filtering in WordPress somewhere? Could you point me in the right direction?
— Tammy Hart (@tammyhart) August 18, 2011
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…
First, we need to create the image size itself:
add_action('after_setup_theme','themename_bw_size'); function themename_bw_size() { add_image_size('themename-bw-image', 100, 100, true); }
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.
add_filter('wp_generate_attachment_metadata','themename_bw_filter'); function themename_bw_filter($meta) { $file = wp_upload_dir(); $file = trailingslashit($file['path']).$meta['sizes']['themename-bw-image']['file']; list($orig_w, $orig_h, $orig_type) = @getimagesize($file); $image = wp_load_image($file); imagefilter($image, IMG_FILTER_GRAYSCALE); switch ($orig_type) { case IMAGETYPE_GIF: imagegif( $image, $file ); break; case IMAGETYPE_PNG: imagepng( $image, $file ); break; case IMAGETYPE_JPEG: imagejpeg( $image, $file ); break; } return $meta; }
Let’s break this down piece by piece:
$file = wp_upload_dir(); $file = trailingslashit($file['path']).$meta['sizes']['themename-bw-image']['file'];
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.
switch ($orig_type) { case IMAGETYPE_GIF: imagegif( $image, $file ); break; case IMAGETYPE_PNG: imagepng( $image, $file ); break; case IMAGETYPE_JPEG: imagejpeg( $image, $file ); break; }
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.
Pretty simple to manipulate images in this way. You could apply one of the many other types of filters available, or change all the images into pictures of bears, or whatever you like, really.