Using ImageMagick with WordPress 2.9.1

Update: I have updated the code below to remove the comment that was shown if the function had been disabled due to an upgrade. It caused a error in WordPress’ RSS feed if left. This hack/mod continues to work in version 2.9.2 of WordPress too.

Ok you might be thinking that I’m obsessed with ImageMagick, and who knows, maybe you’re right. However it, in my opinion, is the best image manipulation package for use on servers. It has a lot of options can composite things I never even considered & most importantly has a excellent memory management system which is great for those on low resource or shared servers.

One thing that bugged me about WordPress is that dispite how complex & how brilliant it is, it still hasn’t included any support what-so-ever for ImageMagick. I mean even phpBB & Gallery2/3 have ImageMagick support and they are open source applications. I can’t really complain though as WordPress is still the best blogging software out there & I couldn’t live without it. ;)

Anyway I have come up with a small fix hack that will make WordPress use ImageMagick. I would only advise doing this if you have a good knowledge of coding, and I will say this only once, back-up your database & your files just in case. Nothing should go wrong, if it does you can always just restore WordPress’ original source files, but have a back-up as it’s better to be safe than sorry.

Since the auto-updater was introduced modifying WP’s core files became dangerous as any changes are overwritten when you update. There are only two ways to get round this, one is not possible in PHP without the help of a PECL package such as ‘runkit’, the other is a little more complicated, but is the best thing available as PECL packages cannot always be installed on shared servers & the like. We are going to provide an alternate function for WordPress to use for resizing images, should the original it uses be missing. The easiest place to put this function, as it won’t be affected by auto updates, is the functions.php file of your theme. The function is this:

Again this is a dirty hack & I claim no resonsiblity for any problems it causes it is up to you whether or not you use it.

This is basically a copy of WordPress’ image resize function, but with all the GD image creation parts taken out and the final resize & save replaced with an exec with the equivalent ImageMagick code in. You may be wondering why I left the image type if in. This is because if the image’s do not match the two types shown the destination file name gets changed to convert all others to a jpg. Conversion will be handled by ImageMagick, but the if is there so that we don’t automatically convert all image types to jpg.

As far as I am aware it doesn’t create any security flaws as all info passed to image_resize() by WordPress is normally checked by WP first. All you have to do now is comment out the image_resize() function in the wp-includes/media.php. The problem of course is that you will have to comment it out again after an upgrade, but at least you don’t have to paste in a function again or even write it again. If there was a filter, or hook to use so you could change the image_resize() function it would be easier, but I haven’t been able to find one.

I hope that helps someone. Let me know should you find any errors or should anyone find any bug/flaws & I’ll try to fix them. ;)

written by

WordPress wizard, coding ninja and all round cool guy. Loves Sci-Fi, geeky stuff, and of course Firefly. Currently a self confessed addict of Korean & Japanese Pop.

Advertisement

43 Comments

Author’s gravatar

?? ????? ????? ?? ??????? ??????? ???? ???????????????? ???????? ??? ?? ???????????? ????, ??? ? ?? ?????????? ?????? ???????. ?? ????? ????? ????? ???????? ??????? ?? ????????????? ? ????? ???????.

Reply
Author’s gravatar

Errrm… Okay! I’m not sure what’s going on here, but all I see is ‘?’s…

Author’s gravatar

Hey Paul!

I’ve been trying out your modification tonight, but can’t seem to get it to work properly.

I have added your function to my theme’s functions.php at the very end, and commented out image_resize() in media.php. All checked and double-checked so far.

However, when I now upload an image in WordPress, I get this error message after the crunching bit is done:

“Warning: Cannot modify header information – headers already sent by (output started at /home/xxx/xxx/wp-content/themes/dailynotes/functions.php:182) in /home/xxx/xxx/wp-admin/async-upload.php on line 26
Are you sure you want to do this?”

The full size image gets uploaded alright, but no resize versions are made.

Any ideas? I’d be happy to provide any other information.

I’m running WordPress 2.9.1 and haven’t tinkered with any files besides these two.

Thanks a lot man, I appreciate your work!

L.

Reply
Author’s gravatar

I’ll reply to myself here. I tried to simply comment out the image_resize function in media.php and insert your version below. This gives me another, and even more strange error message:

“Warning: getimagesize(/home/xxx/xxx/wp-content/uploads/2010/02/vfv-100×150.jpg) [function.getimagesize]: failed to open stream: No such file or directory in /home/xxx/xxx/wp-includes/media.php on line 484″

100×150? Where do it get those dimensions from? My thumbnail sizes are set at 150×150. Hmm, hmm.

I’ve got convert installed att /usr/local/bin/convert and it looks to be functioning on its own.

Strange, this.

Author’s gravatar

Well I’ll assume you changed it but make sure you did change the $magic variable to the correct path for your ImageMagick install. Your error has nothing to do with that but thought I’d check anyway. :lol:

I’m not sure what is going on with the second error, but the first one is a little strange. Can you tell me what code is on line 182 of your functions file. It appears to be trying to change the pages file header after it has loaded, which you cannot do. I’m not sure if that is stopping thumbnail generation, but it could be by causing PHP to stop.

Author’s gravatar

Hi Paul, thanks for your reply. I figured out what was causing all my troubles. In the end it was my version of convert that didn’t like the “mb” after the specified memory amounts.

Changing “-limit memory 50mb -limit map 128mb” to “-limit memory 50 -limit map 128″ worked magic!

Thanks so much for sharing this piece of code!

L.

Reply
Author’s gravatar

Ahh. Yeah some versions don’t like that, please make sure to check that your convert is actually reading those as Megabytes though now that you have removed the mb.

On recent installs of ImageMagick if you leave that off I believe the value is in bytes, so you may have just said -limit memory 50bytes - limit map 128bytes which would be bad. :o

I can’t be certain though. If it starts to take an extrodinary amount of time to create thumbnails from larger images then it is probably in bytes. You could always take out the limit if you don’t need to worry about memory use. I’m on a shared server & so need to keep my memory usage in check. ;)

Author’s gravatar

Oh an forgot to say, no problems. I just have this ‘thing’ about not liking GD. :lol:

Author’s gravatar

Ah, thanks for the heads-up, I’ll look into it.

When it comes to GD – I hear ya man. It totally screws up the color (profiles) on processed images. That’s why I wanted ImageMagick so I could get some more control. Haven’t figured out the profiles yet, but at least I managed to crank up the saturation by 20% on resized images, which means they look at least somewhat like their original sized counterparts.

Good stuff man, good stuff. Thanks again!

L.

Reply
Author’s gravatar

No problem & nice idea. Never really thought about using Imagemagick like that. :)

Author’s gravatar

Check this out:

http://www.catswhocode.com/blog/how-to-overwrite-wordpress-core-functions

No dirty hacks anymore ;-)

Reply
Author’s gravatar

Yes, I already know about add_filter() & add_action() as I use them in both my plugins.

Unfortunately though there needs to be a filter or action hook defined by WP in the function you want to override. If there isn’t one (which there isn’t for image_resize()) then using the filter or actions will do absolutely nothing.

To show you what I mean here is the part in the core that allows you to override bloginfo():

That allows you to override the function. I hope that explains why, untill they add it to the core, we will have to keep editing the core file.

The good news is that someone (I believe) has taken up adding IM to the core as part of the Google Summer of Code that WP are taking part in.

Author’s gravatar

excellent focus , search this from blogsearch plus good luck for you.just tally up the rss feed to my reader,keep update!

Reply
Author’s gravatar

Thanks for the post, I’m working on a plugin for a client that needs to use ImageMagick… any thoughts/speculation on how this might change for WordPress 3.0? Have you found any new hooks in the betas?

Reply
Author’s gravatar

I haven’t had a lot of time to check out any code changes to WP 3, but from what I’ve followed on the mailing lists, and from a quick scan of the media file, I don’t think so.

I believe someone is working on an ImageMagick patch for the WP GoogleCode projects (or at least it was purposed as a project).

I know focus on media has been shifted back to version 3.1 so we might see ImageMagick make an appearence then. We can hope. :)

Author’s gravatar

Hi, thanks for this hack. I’ve tried using it. As I understand it, all I have to do is change the path to imagemagik in that code?

I am trying to use this in WordPress 3. No errors have occured but I’m not sure if it’s working. The outputted images are the same size and quality as if they were done with default WP resizer.

Reply
Author’s gravatar

Yes you just need to change the Imagemagick path. If you are still seeing images being output then it’s probably working as it would error if it wasn’t.

If you really want to make sure it’s working though & you have SSH (shell) access to your server you can always run top -c and see if any convert processes appear when you are uploading some files.

Author’s gravatar

Hi, I tried changing the compression value from 90 to 20 and the outputted files still look the same and have the same file sizes. The path I’m using is definitely right as I’ve confirmed with my server admin.

Just to check, before this bulk of code, there should be only a < ?php (without spaces) right?

Author’s gravatar

Yes, it should be in the functions file of your theme with an opening php tag at the start.

Without being able to check via SSH it’s difficult to know, but yes changing the compression should have changed the size. Are you sure you’ve commented out the normal resize function if the WordPress media.php file. If you don’t do that it won’t work & without that function WP should crash when uploading if Imagemagick isn’t working as it won’t be able to resize images.

Author’s gravatar

Hi, thanks for your help so far. The media file has quite a few lines relating to image resize functions, could you be a little more specific about which lines to comment out? Maybe tell me from which line to which line needs to be commented out? For reference, my current media file is the default WordPress 3.0 one and has 1399 lines.

Author’s gravatar

It’s in the penultimate paragraph of the article:

“All you have to do now is comment out the image_resize() function in the wp-includes/media.php.”

I can’t remember what line it’s on, but just search for image_resize then comment it out using /* at the start and */ at the end. Be careful not to comment out the wrong function though it must just be image_resize and nothing else as there is a function named something very similar.

Hopefully we’ll not have to do hacks like this soon as I believe Imagemagick support is planned for a future version of WP.

Author’s gravatar

So this is the code that I should be looking at right?
function image_resize( $file, $max_w, $max_h, $crop = false, $suffix = null, $dest_path = null, $jpeg_quality = 90 ) {
I’ve tried commenting “image_resize”, tried commenting the whole line, tried commenting “function image_resize”, tried “image_resize
( …. )” and tried commenting “function” up to the end of the whole function.

All with varying results (either upload doesn’t go through successfully or whole site PHP errors).

Reply
Author’s gravatar

You have to comment out the entire function that starts at function image_resize etc & ends with a curly brace ‘}’.

Author’s gravatar

Yep that is one of the things I tried. This appears in the upload results box:

Author’s gravatar

The addition to the function file, setting the imagemagick path and the commenting in the media file are definitely the only things I need to do right?

Author’s gravatar

I’m not sure what’s causing that as my media.php file (WP3) has a comment on the line the error is on?

Yes, those are the only things I have done to my install & it is working fine.

Author’s gravatar

In my media file, line 485 is:

if ( !is_wp_error($resized_file) && $resized_file && $info = getimagesize($resized_file) ) {

Any suggestions?

Author’s gravatar

function image_make_intermediate_size($file, $width, $height, $crop=false) {
if ( $width || $height ) {
$resized_file = image_resize($file, $width, $height, $crop);
if ( !is_wp_error($resized_file) && $resized_file && $info = getimagesize($resized_file) ) {
$resized_file = apply_filters('image_make_intermediate_size', $resized_file);
return array(
'file' => basename( $resized_file ),
'width' => $info[0],
'height' => $info[1],
);
}
}
return false;
}

My ISP support has also suggested the following:

“While yes, this is beyond our scope of support, I would suggest updating the part of the script that generates the file name for that function. You may want to replace that with this PHP variable (depending on how it works):

$_SERVER[“DOCUMENT_ROOT”]

The value of that is simply /xxxx/xxxxx/xxxxxx/sebcastilho.com/html to which you can append wp-content and etc. Beyond that, I’m not sure, but you may want to toy with that function to see if you can get it to work at all on the (gs) Grid-Service.”

Could you just clarify which part he means the replace?

Author’s gravatar

I’m not sure what he means as the same functions used to create the thumbnails before you switched to imagemagick are being used.

It looks as if it’s trying to find the resized images & can’t which would mean (to me at least) that Imagemagick isn’t creating thumbnails. Check to see if the image files that the previous errors gave you exist as Imagemagick doesn’t return errors if it can’t resize images, it just continues on with the script.

Author’s gravatar

Nope the thumbnails indeed do not exist; i.e. the uploaded image isn’t being resized.

Does this mean that the scripting IS able to reach imagemagick, but for some reason the resizing isn’t working?

Reply
Author’s gravatar

Well not always. The first thing to do would be to make sure that the path to imagemagick is correct by using shell access to try and run convert yourself. It’s the only (quick & easy) way to positively identify if the path is okay.

If it is correct then yes for some reason the resizing isn’t working. If your servers imagemagick is below version 6 the carrot (^) flag for square cropping thumbnails will not work, but that shouldn’t stop it from at least creating non square cropped thumbnails.

Author’s gravatar

Does this work with WordPress 3.0.1 ? I put the code in my theme’s functions.php but I’m still getting memory errors. I’ll do some troubleshooting tomorrow.

Reply
Author’s gravatar

Hey Bryan,

As far as I know, yes it still works. It is possible to still get memory errors while using ImageMagick depending on your host, although less likely than with GD.

The tricky part is finding out if IM is generating the thumbnails, as if all works well you shouldn’t really be able to tell the difference (other than larger files shouldn’t cause memory errors).

One way you could test if it is reading the function in your theme file is to comment out the line that runs the IM command & see if you get an error from WordPress when uploading an image. If you do, it’s working. If not, somehow it’s still reading the original image resizing function.

Author’s gravatar

What about the tags?

I mean how i use the tags to generate a custom image? by weight and heigh?

thanks

Reply
Author’s gravatar

Hi Jamesalexx,

I’m not sure what you mean by that. Can you explain a little bit more about what you are trying to do?

Author’s gravatar

hey paul,

found your article on my research for replacing the whole gd_lib with imagick on wp3.0.1 – cause my server guys won’t run the bundled gd version which i need for cropping.

tried it xour way but i get an upload error saying that it couldn’t move the file in the uploads folder. any idea on this one?

and you might have a look at this wp-plugin: http://wordpress.org/extend/plugins/imagemagick-engine/

gretings,
tobi.

Reply
Author’s gravatar

Replying to myself and correcting.. the upload error i mentioned was because my chmod on the monthly upload folder changed somehow. but now i get the same error as Seb on wp 3.0.1 but i have a slight guess:

a) the path to imagick is wrong:
i located mine with system(“whereis convert”); and verifyed with my server admin. but when inserting this path ex. in the ImageMagick Engine Plugin mentioned above it won’t find it there.

b) since your hack is not completly replacing all gd functions from the core, Seb (aswell as i) is still depending on the gd_lib. i figured out that Debian Servers only include gd_lib >2.0 in the non bundled version. there are just some components missing, ex. the crop to thumbnail function.

to solve that problem we would need to change the whole gd lib from the core..

at least that’s my guess

Author’s gravatar

I thought maybe the resize function had changed but I’ve just taken a scan of the file & it doesn’t seem like it.

I would say it sounds like a permissions problem, but I’ve never come across it before. :(

If it works I would say try the plugin, from a quick scan of it looks as if it’s a comprehensive and very well written plugin.

Author’s gravatar

damn you’re fast :)

the plugin is neither working for me since it doesn’t replace all gd functions. i have to change my provider for this project – or rewrite the media.php :)

Author’s gravatar

Although it doesn’t replace the GD functions in the image resize function, it renders them inert as you are overriding them. So not having the bundle version of GD shouldn’t matter I don’t think.

I would check that ImageMagick is in the location shown by ‘whereis’ by trying to resize and image manually using Shell access. If it works I’m not entirely sure what is going on… :(

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">