Drew
Drew

Reputation: 3234

Trying to upload a 1M file locally and i get a Fatal Error

"Fatal error: Allowed memory size of 31457280 bytes exhausted (tried to allocate 9828 bytes)".

This is the error i get but I am only trying to upload a 1mb image. I have increased the memory limit in php.ini and the execution time. I am trying this on a local MAMP server, on a Mac using firefox. This going to be for an online image gallery. Any ideas? Below is the code:

    ini_set("memory_limit","30M");
    if(isset($_POST['submit'])){
      if (isset ($_FILES['new_image'])){
          $imagename = $_FILES['new_image']['name'];
          $source = $_FILES['new_image']['tmp_name'];
          $target = "images/".$imagename;
          move_uploaded_file($source, $target);

          $imagepath = $imagename;
          //below here for the removed code


          $save = "thumbs/uploads/" . $imagepath; //This is the new file you saving
          $file = "images/" . $imagepath; //This is the original file
          $imagesize = getimagesize($file);

          list($width, $height) = $imagesize; 

          unset($imagesize);

          if($width>$height)
            {
                $modwidth = 150; 
                $diff = $width / $modwidth;
                $modheight = $height / $diff;
            }else{
                $modheight = 150; 
                $diff = $height / $modheight;
                $modwidth = $width / $diff;
            }
          $tn = imagecreatetruecolor($modwidth, $modheight); 
          $image = imagecreatefromjpeg($file); 
          $imagecopy = imagecopyresampled($tn, $image, 0, 0, 0, 0, $modwidth, $modheight, $width, $height); 

          imagedestroy($image);
          imagedestroy($im);
          imagedestroy($imagecopy);
          imagedestroy($source);

          $imagejpg = imagejpeg($tn, $save, 100); 
            imagedestroy($tn);
          imagedestroy($imagejpg);

EDIT

This has now been sorted out hopefully. One of my colleagues had a solution all along but neglected to tell me!

Upvotes: 2

Views: 367

Answers (4)

Ciaran McNulty
Ciaran McNulty

Reputation: 18858

It's nothing to do with the (file)size of the image you're uploading, the call that's breaking your memory limit is imagecreatetruecolor().

imagecreatetruecolor() will allocate an area of memory to store a true colour image in with no compression, and use 32 bits (4 bytes) per pixel.

So for a 1024x768 pixel image, for example, imagecreatetruecolour() will use up 1024*768*4 = 3145728 bytes, or around 3MB.

The problem is that this scales up quite dramatically. A 3072x2034 (6 megapixel) image, by the same sort of calculation, needs around 24MB just to be loaded into memory - I would guess this is the sort of size you're dealing with.

The solution is to hand off the processing to something else like imagemagick or NetPBM that will run as a separate process and not count towards the PHP memory limit.

NetPBM is my personal favourite and would look something like:

anytopnm <file> | pnmscale -xysize <dimensions> | pnmtojpg  > <outfile> 

Upvotes: 3

daniels
daniels

Reputation: 19223

Did you restart apache after you increased the memory limit? If yes, then increase a little more.

Upvotes: 0

VonC
VonC

Reputation: 1326784

As mentioned here:

don't forget the imagedestroy() function, or caching your thumbnails - they'll save you a LOT of work down the road.

Upvotes: 1

Michael Madsen
Michael Madsen

Reputation: 55009

You're likely loading the image to do some manipulation of it. That causes the image data to be decompressed, which requires a lot of memory for big images (I think it's about 4 bytes per pixel).

You can choose to either not process the image, or do your processing outside of PHP - for example by invoking ImageMagick or some other program. It depends a bit on what you're trying to accomplish.

Upvotes: 4

Related Questions