Small Update
I’ve just realized that I made a mistake in some of the code. I’ve corrected it so if you were having problems getting this to work that is probably why. The problem is with the ternary operators. If you want the corrected version just scroll down.
Ok so recently I’ve been doing a lot of WordPress theme work & one of the popular ways to generate thumbnail sizes that are different from WordPress’, especially cropped ones, is to use the thumbnail generating script Timthumb. It’s a great script that generates thumbnails at the size you request, it also allows cropping & cache generation to stop the strain on the server. However on a shared or low memory server it can cause problems due to it’s use of GD. GD can be a huge memory hog, Imagemagick however can be told to use a specific amount of memory before dumping to swap or HDD. Great if you are on a shared server or a server with limited memory.
Anyway I altered Timthumb to use Imagemagick as there is no option built in to it. So I thought I’d share it for everyone who wants to use it. I can only share the code I used though & not the script just in case. Don’t want to run into any license problems.
First we define a new constant, just to make it easy to alter our path the Imagemagick’s convert.
define ('CACHE_SIZE', 2500); // number of files to store before clearing cache
define ('CACHE_CLEAR', 5); // maximum number of files to delete on each cache clear
define ('VERSION', '1.09'); // version number (to force a cache refresh
define ('MAGIC_PATH', 'path/to/convert'); // path to imagemagick's convert
Now that we have an easy way to call our convert path we can continue. First though a quick note. Timthumb has support for filters, due to Imagemagick having different parameters I have not added support for them. Ok, now that’s out of the way we can get back to the code. I have chosen to comment out parts that are made redundant, however if you feel the need you can probably delete them.
Now you need to find this code:
// open the existing image
$image = open_image($mime_type, $src);
if($image === false) {
displayError('Unable to open image : ' . $src);
}
// Get original width and height
$width = imagesx($image);
$height = imagesy($image);
Replace it with the following:
// Get original width and height
list($width, $height) = @getimagesize($src);
You need to keep the width & height stuff as well as the code that figures out the cropped width & height. So next you need to comment out, or delete the following:
// create a new true color image
$canvas = imagecreatetruecolor( $new_width, $new_height );
imagealphablending($canvas, false);
// Create a new transparent color for image
$color = imagecolorallocatealpha($canvas, 0, 0, 0, 127);
// Completely fill the background of the new image with allocated color.
imagefill($canvas, 0, 0, $color);
// Restore transparency blending
imagesavealpha($canvas, true);
Next comment out or delete:
imagecopyresampled( $canvas, $image, 0, 0, $src_x, $src_y, $new_width, $new_height, $src_w, $src_h );
You can probably delete the entire next bit, but I left it in and commented it out just in case:
else {
// copy and resize part of an image with resampling
//imagecopyresampled( $canvas, $image, 0, 0, 0, 0, $new_width, $new_height, $width, $height );
}
Comment out the entire filters section up until the line that says:
// output image to browser based on mime type
show_image($mime_type, $canvas, $cache_dir);
Comment out or delete the line imagedestroy($canvas); as well. Next change the line above to this:
// output image to browser based on mime type
show_image($src, $mime_type, $cache_dir, $new_width, $new_height, $zoom_crop);
Next change this:
function show_image($mime_type, $image_resized, $cache_dir) {
to this:
function show_image($src, $mime_type, $cache_dir, $new_width, $new_height, $zoom_crop) {
Comment out or delete:
imagepng($image_resized, $cache_file_name, $quality);
Underneath that put the following:
$new_width = is_numeric($new_width) ? $new_width : '100';
$new_height = is_numeric($new_height) ? $new_height : '100';
$crop = ($zoom_crop) ? "^ -gravity center -extent {$new_width}x{$new_height}" : "";
exec(MAGIC_PATH." -limit memory 50mb -limit map 128mb -size {$new_width}x{$new_height} '{$src}' -thumbnail {$new_width}x{$new_height}{$crop} '{$cache_file_name}'");
Finally comment out or delete the line:
imagedestroy($image_resized);
The two tenaries are to protect against possible non numeric values being used for the width & height.
That is just about it. I have left the quality out as I don’t really have a use for it, but should you want it all you need to do is change the value of the quality variable to something out of 100% instead of it multipling by 0.09. Then give it to Imagemagick through the -quality xx% parameter.
I hope that helps someone & hope you all had a great Christmas & have a great new year.
Discussion: 7 Comments
Hi Interesting, I use the same theme as you and have massive issues with TimThumb, your solution looks a little tricky for me to follow though.
I would like to know what plugin you are using for on this site for the four ad boxes at the top if possible mate
Not a problem. The plugin is called Adrotate & is available from the WordPress plugin directory. It requires a little setup but not too much & most of it is done via the admin.
Hope that helps.
Forgot to mention that this patch will only be usefull if you have Imagemagick installed. If you don’t then unfortunately there isn’t a lot you can do. One thing I did find is that if you use timthumb on a large site with a lot of images Timthumbs pre-set cache amount may be too small. If you open the timthumb cache folder in a SFTP client and see if there a 250 files. If so your problem may be that you have more thumbs for timthumb to create than it can cache. This happened on a image heavy client site I worked on recently.
If that is the problem the just open up the timthumbs file and increase the cache number near the top of the file. Hope that helps a little more.
It was a great moment that I have landed here in your post. I’m really learning a lot. Thanks. Keep it up. You’re helping lot of people.
Hi Paul,
If you don’t mind can I know where I can get Imagemagick? So that i can also use this.
Imagemagick is a unix/windows program used by servers to manipulate images, if can be installed quite a few different ways, depending upon your platform.
On Windows you just search on google for imagemagick & download the windows binary. If you are on Ubuntu or a Unix platform with access to apt or a software repository there is normally a version available on there. Finally you can compile it manually using the instructions on Imagemagick’s website.
I haven’t heard about this before. I want to thank you for the codes you have preferred and shared to us. It will really help a lot to me and to everyone that will see this.