Uploading images with PHP and hitting the script memory limit - php

I am trying to upload a JPG image using a PHP script, but the image is keeps causing my script to time out and die giving this error:
Fatal error: Allowed memory size of 33554432 bytes exhausted (tried to allocate
2136 bytes) in image.php on line 38
How can I prevent the upload from taking place if the image is too big, or have this error fail gracefully?

The actual problem is not with the initial file size but with the dimensions of the image itself (heightwidthcolorDepth), since you don't have access to this information before the file has been uploaded for security reasons, you should probably use an uploader written in Flash, Java or Silverlight since they DO have access to this information beforehand.
After the upload you can check if the image will exceed your memory limit by calculating the dimensions of the (uncompressed) image by using getimagesize and using the returned width, height and bit depth.
Best of luck.

http://php.net/manual/en/features.file-upload.common-pitfalls.php says:
If a memory limit is enabled, a larger memory_limit may be needed. Make sure you set memory_limit large enough.

You can limit image size or any other file upload size on couple of ways,
via php.ini, upload_max_filesize = 10M
via invisible tag such as this(10k):
<input type="hidden" name="MAX_FILE_SIZE" value="10000" />
I Would not recommend increase memory limit if you don't know what kind of implications it can have on your server configuration.

Just set the memory limit higher for that particular script only by using ini_set.
At the beginning of your image processing script:
ini_set('memory_limit', '64M');
This error is generally caused not by image file size, but rather image resolution. So you can run some check for the size of the image. Run some tests to see what's acceptable under your current memory limit, and if the resolution is higher then kill the process and return an error to the user.

$size=filesize($_FILES['image']['tmp_name']);
will give you the size of the file in the global $_FILES array. After this, just compare $size to the maximum size you want.
Check out thie filesize() api: http://php.net/manual/en/function.filesize.php

Is this happening with all upload attempts regardless of file size? I have only experienced this sort of problem when there has been a scripting error - usually a loop that is out of control.

Related

PHP Compress Image

I am trying to compress an uploaded image using imagefromjpeg but I get this error:
Fatal error: Allowed memory size of 67108864 bytes exhausted (tried to allocate 24000 bytes)
The image is only 13215317 bytes big - why do I keep getting this error? I can not ramp up the memory for the server myself - so is there a way to compress without loading the entire image at once?
$image = imagecreatefromjpeg('../../uploads/DSC_0230.jpg');
imagejpeg($image, '../../uploads/DSC_0230.jpg.new', 0.8);
imagedestroy($image);
Loading an image into PHP this way will first uncompress the JPEG into raw pixel data in memory, and then generate the new version. It will therefore take memory equivalent to two raw bitmaps at the image's resolution, plus the other overhead of PHP and your script.
Since all you're doing is recompressing the image with different options, you will probably have better performance with a tool built for just that job, such as jpegtran or jpegstrip, or a general image manipulation tool like ImageMagick.
You could then call those from your PHP script using shell_exec - being very careful that you have validated the filename so that someone can't use it to run arbitrary commands.
Issue:
Your hosting provider offers you service with only a 64Mb memory limit.
Your image upload has a larger than 64Mb memory usage as uncompressed raw pixel data.
Solutions:
1) Increase your memory limit in PHP.ini file, typically with :
memory_limit = 128M
2) Increase your memory limit on your page only, editing the php.ini only for that page execution :
ini_set('memory_limit','128M');
3) Limit the size of the original file upload.
there are a few ways to do this, so please read the PHP manual as well as reaseach some useful posts found via Google Searching.
4) You can also try and resize the image before uploading.
From your statement that you cant edit the PHP.ini with ini_set then it looks like you should use option 4 and 3.
Also, your current code is incorrect.
imagejpeg($image, '../../uploads/DSC_0230.jpg.new', 0.8);
The compression value should be an integer between 0 and 100. to correctly set the saved JPEG to a proper compression level:
imagejpeg($image, '../../uploads/DSC_0230.jpg.new', 80);
This will save the image to a value of 80 compression(the value it looks like you're attempting with 0.8).

php image copy/crop/resize memory limits [duplicate]

Fatal error: Allowed memory size of 33554432 bytes exhausted (tried to allocate 4912 bytes) in /var/www/development/example/system/libraries/Image.php on line 130.
The JPEG image in question does not have a particularly large file size (741 KB). We've used this same code to rebuild larger images. However, the image does have unusually large dimensions (4912px x 3264px). Would this have an effect?
What determines memory usage when PHP is rebuilding an image? Is it just the file size? The dimensions? The colour density? The file type?
The line on which it broke was
$f1 = 'imagecreatefrom' . $tag;
$src = $f1($file);
I think that's enough context. It didn't get as far as trying to rebuild the image. Loading it into memory was enough to break it.
As riky said, set the memory limit higher if you can. Also realize that the dimensions are more important than the file size (as the file size is for a compressed image). When you open an image in GD, every pixel gets 3-4 bytes allocated to it, RGB and possibly A. Thus, your 4912px x 3264px image needs to use 48,098,304 to 64,131,072 bytes of memory, plus there is overhead and any other memory your script is using.
Increase your memory buffer size
php_value memory_limit 64M in your .htacess
or ini_set('memory_limit','64M'); in your php file
It depends your implimentation. last time when I was working on csv file with more then 500000 records, I got the same message. Later I introduce classes and try to close the open objects. it reduces it memeory consumption. if you are opening an image and editing it. it means it is loading in a memory. in that case size really matter. if you are operating multiple images. I will record to one per image and then close that image. In my experience when I was working on pdf artwork files to check the crop marks. I was having the same error.
//you can set the memory limits values
// in htaccess
php_value memory_limit 64M
//or in you using following in php
ini_set('memory_limit', '128M');
//or update it in your php.ini file
but if you optimize your code. and use object oriented aproach then you memory consumption will be very less. because in that every object has its own scope and out of that scope it is destroyed.
The size of the used memory depends on the dimension and the color bit depth.
I also ran in to that problem a few years ago, while building a portfolio-website for photographers. The only way to properly solve this is to switch your image library from GD to imagick. Imagick consumes far less memory, and is not tied to the PHP memory limit.
I have to say that the images the photographers uploaded were up to 30MP. And setting the memory limit to over 1024MB makes no sense in my eyes.

PHP Upload images with width greater than 2000 pixels causes crash

When users upload an image to my server (Shared Server), the server shoots an error when the file has a width > 2000 pixels. It doesn't have to do with the filesize -- I can upload a 1 mb file at 2000 width and it still crashes. If I upload a 1 mb file at 1000 pixels, it works fine.
This is the error I get.
Fatal error: Allowed memory size of 67108864 bytes exhausted (tried to allocate 20000 bytes)
I am using SimpleImage plugin (http://www.white-hat-web-design.co.uk/blog/resizing-images-with-php/) and CakePHP framework.
I read both PHP File Upload greater than upload_max_filesize and error and Large File Upload Errors with PHP but neither really addressed this issue.
Anyone ever come across this? Any ideas?
you might be hitting the memory limit...
try increasing the memory_limit directive in your "php.ini"
or
add the following on the top of your php script,
ini_set('memory_limit', '128M');
if you want to upload an image of size greater that 2000px using php store it in database .
Create a table and then store the image in it using BLOB-Binary Lodge Object
Use file_get_contents to get the contents of the image and then store it.
Than the server won't crash
add this to the top of your controller that is receiving the upload
ini_set('memory_limit', '256M');
change the limit value as needed.

PHP rebuilding images: memory usage

Fatal error: Allowed memory size of 33554432 bytes exhausted (tried to allocate 4912 bytes) in /var/www/development/example/system/libraries/Image.php on line 130.
The JPEG image in question does not have a particularly large file size (741 KB). We've used this same code to rebuild larger images. However, the image does have unusually large dimensions (4912px x 3264px). Would this have an effect?
What determines memory usage when PHP is rebuilding an image? Is it just the file size? The dimensions? The colour density? The file type?
The line on which it broke was
$f1 = 'imagecreatefrom' . $tag;
$src = $f1($file);
I think that's enough context. It didn't get as far as trying to rebuild the image. Loading it into memory was enough to break it.
As riky said, set the memory limit higher if you can. Also realize that the dimensions are more important than the file size (as the file size is for a compressed image). When you open an image in GD, every pixel gets 3-4 bytes allocated to it, RGB and possibly A. Thus, your 4912px x 3264px image needs to use 48,098,304 to 64,131,072 bytes of memory, plus there is overhead and any other memory your script is using.
Increase your memory buffer size
php_value memory_limit 64M in your .htacess
or ini_set('memory_limit','64M'); in your php file
It depends your implimentation. last time when I was working on csv file with more then 500000 records, I got the same message. Later I introduce classes and try to close the open objects. it reduces it memeory consumption. if you are opening an image and editing it. it means it is loading in a memory. in that case size really matter. if you are operating multiple images. I will record to one per image and then close that image. In my experience when I was working on pdf artwork files to check the crop marks. I was having the same error.
//you can set the memory limits values
// in htaccess
php_value memory_limit 64M
//or in you using following in php
ini_set('memory_limit', '128M');
//or update it in your php.ini file
but if you optimize your code. and use object oriented aproach then you memory consumption will be very less. because in that every object has its own scope and out of that scope it is destroyed.
The size of the used memory depends on the dimension and the color bit depth.
I also ran in to that problem a few years ago, while building a portfolio-website for photographers. The only way to properly solve this is to switch your image library from GD to imagick. Imagick consumes far less memory, and is not tied to the PHP memory limit.
I have to say that the images the photographers uploaded were up to 30MP. And setting the memory limit to over 1024MB makes no sense in my eyes.

Image size reduction in PHP

In cases such as this error:
Fatal error: Out of memory (allocated
31981568) (tried to allocate 3264
bytes)
Can I use the GD lib to reduce its file size first before getting to this stage?
In short: no.
GD uses memory to reduce the size of an image, if the image is too big the memory limit is exceeded and an error is given.
You can calculate how big an image can be so you can stay under a certain memory limit here: http://www.dotsamazing.com/en/labs/phpmemorylimit
An option, although an unpopular one with shared hosts, is increasing the memory limit, you can do this with ini_set() or in an .htaccess file. Please check if your host allows this. If you have your own host, configure Apache accordingly.
An (also mentioned) option is using Imagemagick, a program that runs on the server that you can call to do the resizing for you. The memory limit for this program can be different than the one for PHP, but there probably will be a limit as well. Contact your host for more info.
You can instead set a higher memory limit.
ini_set('memory_limit', $file_size * 2);
Because if you want to reduce the size using GD, you still need to allocate memory for that file before you can reduce the size.
Also remember to set a file size limit to your image uploads.
You can use the filesize() function to check the file size before reading/opening the file.
Are you reading a file from disk with a PHP script?
This is obviously continuing from your previous post. If I remember rightly it's an uploaded image you're working with? If so what is the size of the image? If it's really large you should consider limiting the size of image uploads.
That would happen when u want the memory to do more than it can .. you might want to look into imagemagick , so instead of resizing via PHP just send request to imagemagick to do the resizing.
Or the easier way would be to increase the memory limit per script of php scripts via ini.

Categories