I'm trying to process a directory of JPEG images (roughly 600+, ranging from 50k to 500k) using PHP: GD to resize and save the images but I've hit a bit of a snag quite early in the process. After correctly processing just 3 images (30K, 18K and 231K) I get a Allowed memory size of 16777216 bytes exhausted PHP Fatal error.
I'm cycling through the images and calling the code below:
list($w, $h) = getimagesize($src);
if ($w > $it->width) {
$newwidth = $it->width;
$newheight = round(($newwidth * $h) / $w);
} elseif ($w > $it->height) {
$newheight = $it->height;
$newwidth = round(($newheight * $w) / $h);
} else {
$newwidth = $w;
$newheight = $h;
}
// create resize image
$img = imagecreatetruecolor($newwidth, $newheight);
$org = imagecreatefromjpeg($src);
// Resize
imagecopyresized($img, $org, 0, 0, 0, 0, $newwidth, $newheight, $w, $h);
imagedestroy($org);
imagejpeg($img, $dest);
// Free up memory
imagedestroy($img);
I've tried to free up memory with the imagedestroy
function but it doesn't seem to have any affect. The script just keeps consistently choking at the imagecreatefromjpeg
line of code.
I checked the php.ini and the memory_limit = 16M
setting seems like it's holding correctly. But I can't figure out why the memory is filling up. Shouldn't it be releasing the memory back to the garbage collector? I don't really want to increase the memory_limit setting. This seems like a bad workaround that could potentially lead to more issues in the future.
FYI: I'm running my script from a command prompt. It shouldn't affect the functionality but might influence your response so I thought I should mention it.
Can anyone see if I'm just missing something simple or if there's a design flaw here? You'd think that this would be a pretty straightforward task. Surely this has to be possible, right?
You can adjust the memory allocation on the fly from within a PHP file. You simply have the code ini_set('memory_limit', '128M'); (or whatever your desired allocation is). You can remove the memory limit (although machine or instance limits may still apply) by setting the value to "-1".
You can find the php. ini file in the public_html for your website and right-click on the file to Edit it. Look for the line defining the memory_limit variable and set the value accordingly. Then, save the changes and reload your site to see if the PHP “Allowed Memory Size of Bytes Exhausted” error has been resolved.
It's possible that one or more of your images actually inflate to 16M in raw memory. One way to check is to open it in Photoshop or Irfanview and check the color space and pixel dimensions.
It doesn't take much to reach 16M, for example, consider a "lowly" 6 megapixel camera. It creates a 3072 pixel by 2048 pixel image. At a byte per color (RGB) the raw size is:
3072 x 2048 x 3 = 18,874,368
So, you might want to increase the memory according to the largest images you expect to process. But you have to consider their raw size.
In some cases you simply cannot anticipate the highest memory allocation that will be needed by the images you are about to process. To prevent a crash, you may include following commands before and after your loop :
register_shutdown_function ('my_function');
$mem_limit = ini_get ('memory_limit');
ini_set ('display_errors', false);
ini_set ('memory_limit', '400M'); // some high value
(...your process...)
ini_set ('memory_limit',$mem_limit);
And place within the function "my_function ()" the code that will handle the crash.
ini_set('memory_limit', '64M');
problem solved
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With