PHP, GD & Memory Limits Plus How To Install ImageMagick

/ PHP / by Paul Robinson / 7 Comments
This post was published back on February 22, 2009 and may be outdated. Please use caution when following older tutorials or using older code. After reading be sure to check for newer procedures or updates to code.

I thought I’d make this little tid bit of a post for anyone who is interested. I was recently using GD to make an uploader, as I mentioned in the last post. Yesterday someone contacted me saying it produced an error, but the error was blank. Very odd! So I shut it down so I could do some debugging & it turned out the error was a one of these:

Fatal error: Allowed memory size of whatever bytes exhausted (tried to allocate so-many bytes) in path/to/file in line something

You’ve probably seen it before. If not, it basically means PHP ran out of it’s allocated memory. On a private server this probably won’t happen very often since you have the whole computers RAM to work with, on a shared server though, like this one, it can happen quite often since you are limited to the amount of memory you can use. In Dreamhost’s case it is 90MB which is quite a lot.

What’s Your Point?

Well this image was a jpg & was only 1.4MB so why did it run out of all 90MB of memory? Well let me explain and hopefully you can avoid this problem. To make a thumbnail from a jpg you use createimagefromjpeg(), the problem with this function is that it uncompresses the image to work with it. So to know if you are going to run out of memory you need to know the uncompressed image size. Here is the sum to work it out.

pixels in width X pixels in height X 3 = size in bytes

The 3 in the sum relates to the number of channels in the image (RGB).

Now in the case of my image it was 4042 X 4992 X 3 = 60532992 bytes which is approximately 57.7MB which is under my memory limit. However consider another person uploading while the first image is still being processed, and/or add the overhead from your applications standard page loads (sometimes up to 40MB in WordPress) and you’ve exhausted your memory limit.

Flippin’ Great! What Can I Do About It?

Well not a lot unfortunately. You can either stop using GD and use ImageMagick if you have SSH access to your server and can be bothered to figure out how to install it. It may of course be already installed which is great. If not then the best thing you can do is do something to work out if the image is going to be too big before it’s processed and give back an error message.

Here is an example of something you could use, and could probably be easily customised to fit any uploader.

This will get the size info for the image from the temp file stored after the file has been uploaded. It will then do the sum and check to see if it is greater than the memory limit. You will need to change 94370000 to your memory limit in bytes. You could probably use ini_get("memory_limit") instead, but some shared servers set your permissions so you can’t run that command, my old host used too.

Is That What You Did?

Nope, I installed ImageMagick, but there is a wiki page on the Dreamhost wiki on how to do it on Dreamhost. It’s changed slightly since the new version, but it was still easy thanks to the kind person who wrote the wiki page. Generally it’s as easy this:

Normally though ImageMagick will try to install into /usr/local/ which on a shared server isn’t possible. Instead you can change the configuration like this:

If you want perlmagick installed you will need to change the installation directory of that too use --with-perl-options=PREFIX=$HOME/local so it installs perlmagick in a place it has permissions to. I ended up having a problem with perlmagick as it always failed to install because of lperl being missing. After contacting Dreamhost and finding they couldn’t find any reference to it & then checking the latest perl version was installed (it was) I just decided to use the --without-perl switch since I don’t really use perl. I could always compile my own version of perl in my home directory with lperl installed, but it’s working fine without it.

I hope this is of some help to someone. I might make a tutorial a little later with how to use ImageMagick to create thumbnails, it can always be a little hard at first, but it’s extremely powerful & fast. I mean really fast.

If you want to see what ImageMagick can do then head to this image gallery at Natural Tys that I built. It generates thumbnails, when the admin uploads an image, with a frame & transparent shadow and it’s all done dynamically in ImageMagick. Clever, huh? More on that a little later though.

Any questions, ideas or have you noticed a mistake I’ve made. Drop me a comment and let me know.

7 Comments

Author’s gravatar

hi, so you mean imageMagick needs less memory as compared to GD, right?

Reply
Author’s gravatar

If you mean in general I have no idea. I would think so, but because of it’s ability to dump memory useage to HDD space it allows you to run processes on servers that would normally run out of memory. I can now thumbnail images with sizes upwards of 6000x6000px GD stops at 5000×5000-ish. ImageMagick is sometimes slower though although is more powerfull overall IMO.

Author’s gravatar

I’d love to know where you got the x5 from.

For a 24bit image it’s 3 bytes per pixel (8 bits x 3 = 24) multiplied by the number of pixels.
For a 32bit image it’s 4 bytes per pixel (6 bits x 4 = 32) multipled by the number of pixels.

5x would have to be a 40bit image.

So, for an image of 4042 X 4992 that gives us:

24bit: 3 x 4042 x 4992 = 60532992 / 1024*1024 (to get megabytes) = 57.73MB
32bit: 4 x 4042 x 4992 = 80710656 / 1024*1024 (to get megabytes) = 76.97MB

Both of which are still far enough below the 90MB limit you discuss. The problem lies elsewhere, the solution to which I am still looking for.

Please don’t pull magic numbers out of thin air when they’re open to all to see, if you’re going to use a number like 5, explain where it comes from as I have above.

Good day.

Reply
Author’s gravatar author

Hi,

I apologise for the incorrect information, but the way you ‘corrected’ me was exceptionally rude and totally uncalled for. A simple correction will suffice.

For anyone looking for the simplest way to work out the uncompressed size of a ‘standard’ 24-bit JPG you can use:

Mbytes = (H pixels * V pixels * 3) / 1048576

It as served me well for a long time since I wrote this post.

5 is actually for a CMYKA image which holds a 32-bit CMYK & 8-bit Alpha information. No idea why I used it here, it is too long go to remember.

In regards to the problem mentioned in this post. The problem actually did lie with GD consuming too much memory. But it was more in regards to having two people upload images consuming 57MB of memory at nearly the same time.

Older Comments
Newer Comments

Leave a Reply

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

This site uses Akismet to reduce spam. Learn how your comment data is processed.

I'll keep your WordPress site up-to-date and working to its best.

Find out more