Mike McLin
Mike McLin

Reputation: 3637

Resize images too large for GD Library on my server

I almost always have a PHP resize script (using GD) in websites for my clients. No matter how many times I tell them to resize their huge 7MP images from their digital camera before uploading them, they still never do it. The result is an "Out Of Memory" error from the server, and the image doesn't get resized, because the original image was too large resolution-wise.

Is there a better way to resize really large images? Is there a service that offers an API that I could tap into through my script to resize these large images?

Upvotes: 6

Views: 8562

Answers (7)

M'sieur Toph'
M'sieur Toph'

Reputation: 2676

I got stuck for days (and nights) with this problem.

Moreover, providers memory limit differs from one to another. And change the memory_limitin PHP does not work on shared servers, providers usually limit the ram even if phpinfo() says that you got 128Mo (1and1 limits RAM to 60Mo per process for example).

But I finally found something quite efficient here : http://www.imagemagick.org/Usage/files/#massive

It needs imagemagick, but I discovered that most of the providers natively provides this on their servers, even shared ones.

exec('env MAGICK_TMPDIR=<tmp_dir> nice -5 convert -limit memory 32 -limit map 32 -resize 800x600 huge.jpg reasonable.jpg'); 

As it's said :

  • env MAGICK_TMPDIR=<tmp_dir> set up a temp directory for imagemagick to simulate ram (kind of)

  • nice -5 is also a unix command to change the priority of a process (http://en.wikipedia.org/wiki/Nice_(Unix))

  • convert ... is the imagemagick command line

The real deal is about -limit memory 32 and -limit map 32. This is the way you limit the memory used by the binary (here : 32Mo). You will probably need to fit the values to match the values of your server (Generally PHP tells you the maximum allocated memory when it gives you the Fatal Error. I suggest you to divide this value by 2 or 4 to be confortable).

I also needed to put some other lines in my PHP to avoid some collateral issues :

ignore_user_abort(true); // ignore user abort : let the script finish resizing even if user aborts
set_time_limit(0); // ignore server timeout
putenv('MAGICK_THREAD_LIMIT=1'); // limit the number of thread for the binary. Very important in my case 

Hope all that will help ...


To know if convert is available on your server, you can try this (in PHP) :

$out = array();
exec('which convert 2>&1', $out);
print_r($out); 

That will gives you the path of the binary, if exists.

Upvotes: 2

Magnus
Magnus

Reputation: 25774

I had spent some time trying to debug PHP code that used GD directly, but failed on large images and on a subset of images that seemed to have minor errors that choked GD.

But then I found phpThumb (http://phpthumb.sourceforge.net/), and I'm never going back. After adding two PHP files to my web directory (phpthumb.class.php and phpthumb.functions.php) I was able to use the following code to generate my thumbnails:

include("phpthumb.class.php"); 

// Load data into phpThumb object and set parameters
$phpThumb = new phpThumb();
$phpThumb->setSourceData(file_get_contents($_GET['filename']));
$phpThumb->setParameter('w', $width);  // Set width
$phpThumb->setParameter('h', $height); // Set height
$phpThumb->setParameter('zc', 1);      // Specify zoom-crop (instead of stretch)
$phpThumb->setParameter('q', 100);     // Specify quality

// Generate & output thumbnail
$phpThumb->GenerateThumbnail();        // Generate the thumbnail
$phpThumb->OutputThumbnail();          // Output it to browser
$phpThumb->RenderToFile("$thumbname"); // Output it to file
$phpThumb->purgeTempFiles();           // Clean up

Boom, works like a charm, is pretty fast and has no problems with large files. Also, it can use either GD or ImageMagick, depending on what's available on the server, so it's relatively portable.

Upvotes: 1

zack
zack

Reputation:

Just make them resize it smaller before they upload it. MAX_FILE_SIZE

Upvotes: 1

enkrs
enkrs

Reputation: 136

If you have available ImageMagick api in your PHP configuration - use it! ImageMagick doesn't get counted in PHPs memory_limit and therefore can work with bigger files.

If you realy have no control over the server, the quick and very bad workaround is - after getting the image file from $_POST, first check the dimensions with:

<?php
$image_size = getimagesize("yourfile.jpg")
$mem_usage = $image_size[0] * $image_size[1] * 4 //4 bytes per pixel (RGBA)
if ($mem_usage > $mem_aviable) {
    die ('Please upload smaller pic. I tell you that all the time.  '.
         'Resize yout huge 7MP images from your digital camera '.
         'before uploading them.'); //Better put something more polite here.
}

Upvotes: 3

Question Mark
Question Mark

Reputation: 3606

how about uploading them then queuing the resize job, a command line php script can then pick up and process (faster and can have a separate memory limit and execution time)

Upvotes: 1

Greg
Greg

Reputation: 321698

You could shell out to an external programme, for example using convert.

Upvotes: 1

Lliane
Lliane

Reputation: 831

You can call Imagemagick to resize the picture from your php page, but there's a security matter then if you allow system calls

Any API will use a lot of Memory, you can change your php memory_limit aswell.

Upvotes: 3

Related Questions