Page 1 of 1

Using GD - "Fatal error: Allowed memory size of..."

Posted: Fri Oct 20, 2006 12:38 pm
by revof11
I am getting the following error utilizing the GD library in PHP:
Fatal error: Allowed memory size of 268435456 bytes exhausted (tried to allocate 35152 bytes) in /var/www/html/_s/php/Images.php on line 146
I started getting this utilizing 8M, but I tried altering my php.ini file to utilize 256M (as you can see) and am still receiving the error. Everything runs fine in my code until I try and actually write the new file data. I would appreciate any help anyone can give me in trying to figure out why this is happening.

Line 146 is:

Code: Select all

$imgResource = imagecreatefromgd($sourceFileLocation);
The file does exist... because I am running the following line earlier in the code without any errors/failures popping up:

Code: Select all

getimagesize($sourceFileLocation)
Is there an alternative way to load the file as an "image resource"?
I want the user to be able to upload any time of file, so I was trying to avoid usage of imagecreatefrom(xxx) functions.

Posted: Fri Oct 20, 2006 1:00 pm
by s.dot
What exactly are you trying to do? Any type of file can be uploaded and passed into the $_FILES superglobal.

$_FILES['somefile.txt']
$_FILES['somemovie.mpg']
etc..

Posted: Fri Oct 20, 2006 2:44 pm
by revof11
I wrote a method that alters images.
The image is already uploaded and moved to its "permanent location".

All I want to do is open up the file, make a change, and then save it back.
Just resizing right now... but I want to eventually run some image layovers (watermarking, etc.)

Posted: Fri Oct 20, 2006 2:49 pm
by feyd
Are you processing multiple files at a time, or is this happening to one file?

Posted: Fri Oct 20, 2006 3:13 pm
by revof11
Just one file at a time.

For the time being, I have switched to use the getimagesize method's third array value (an integer representation of the image type) and am switching on it in order to determine GIF, JPEG, PNG, etc... I would really just like to coondense it (if at all possible) so that I can ditch the switch.

Posted: Fri Oct 20, 2006 3:19 pm
by feyd
Post the whole script please. ..and make sure to use the

Code: Select all

tags.

Posted: Fri Oct 20, 2006 3:23 pm
by revof11

Code: Select all

if ( !extension_loaded('gd') )
    {
      die("PHP GD extension not loaded on server!<br />Please contact the system adminsitrator!");
    }
      
    // what type of image is this?
    $imageBaseData = getimagesize($source);
    switch ( $imageBaseData[2] )
    {
      // ---------------------------
      // GIF
      // ---------------------------
      case 1:
        // create a new image with the new width and height
        $newImage = imagecreatetruecolor($width, $height);
        $newImageBackground = imagecolorallocate($newImage, 0, 0, 0);
        ImageColorTransparent($newImage, $newImageBackground);  // make the new image completely transparent
        imagealphablending($newImage, false);                   // turn off the alphs blending to keep the alpha channel
        imageSaveAlpha($newImage, true);                        // make sure alpha saving is on
    
        // resize the file
        $imgResource = imagecreatefromgif($source);
        imagecopyresampled($newImage, $imgResource, 0, 0, 0, 0, $width, $height, imagesx($imgResource), imagesy($imgResource));

        // write the new image & destroy the temp
        imagegif($newImage, $destination);
        imagedestroy($newImage);
        break;
        
      // ---------------------------
      // JPEG
      // ---------------------------
      case 2:
        // create a new image with the new width and height
        $newImage = imagecreatetruecolor($width, $height);
        $newImageBackground = imagecolorallocate($newImage, 0, 0, 0);
        imagealphablending($newImage, true);
        
        // resize the file
        $imgResource = imagecreatefromjpeg($source);
        imagecopyresampled($newImage, $imgResource, 0, 0, 0, 0, $width, $height, imagesx($imgResource), imagesy($imgResource));
        
        // write the new image & destroy the temp
        imagejpeg($newImage, $destination);
        imagedestroy($newImage);
        break;
       
      // ---------------------------
      // PNG
      // ---------------------------
      case 3:
        // create a new image with the new width and height
        $newImage = imagecreatetruecolor($width, $height);
        $newImageBackground = imagecolorallocate($newImage, 0, 0, 0);
        ImageColorTransparent($newImage, $newImageBackground);  // make the new image completely transparent
        imagealphablending($newImage, false);                   // turn off the alphs blending to keep the alpha channel
        imageSaveAlpha($newImage, true);                        // make sure alpha saving is on
    
        // resize the file
        $imgResource = imagecreatefrompng($source);
        imagecopyresampled($newImage, $imgResource, 0, 0, 0, 0, $width, $height, imagesx($imgResource), imagesy($imgResource));

        // write the new image & destroy the temp
        imagepng($newImage, $destination);
        imagedestroy($newImage);
        break;
        
      // ---------------------------
      // err
      // ---------------------------
      default:
        die ( sprintf("Unhandled image type (%d)!<br />Please only upload JPEG, GIF or PNG images.", $imageBaseData[2]) );
        break;
    }

Posted: Fri Oct 20, 2006 3:42 pm
by feyd
How large are these images (dimensions)? Where does $width/$height get set and what are they?

Does adding an imagedestroy() on the source image after the resampling call, affect the memory usage?

Posted: Fri Oct 20, 2006 3:44 pm
by revof11
The images aren't exceeding 1024x768...
putting the destroyimage() call on was me attempting to try and get back some memory.

It didn't seem like a necessity, but is there under "good practice" and "what the #$%@ is going on with the memory use?"

Posted: Fri Oct 20, 2006 4:02 pm
by feyd
revof11 wrote:putting the destroyimage() call on was me attempting to try and get back some memory.
I wasn't asking why there was one. I was asking if you added another that destroyed the source image, does it help.

Posted: Fri Oct 20, 2006 4:12 pm
by Flamie
Well, a PHP script has a maximum memory it can use at the same time, you have two solutions to this:
->Break the image into smaller images and process all of them individually (make sure you imagedestroy() each of them after using it tho to free memory)
->Use the command in htaccess to modifiy the maximum size a script can use with this line:
php_value memory_limit 16M
where 16M stands for 16mb, you can make it more/less depending on how big your images are.

Posted: Fri Oct 20, 2006 4:34 pm
by wtf
I had a simmilar issue while back and all we've done to get it going was to increase memory size in php.ini, then restart the apache and it worked just fine

viewtopic.php?t=52869

Posted: Fri Oct 20, 2006 5:39 pm
by revof11
Breaking up the files fixed EVERYTHING.
I was actually able to even run uploads of pictures from my camera (3MB to 5MB).

I broke them down extremely small, and that worked extremely well.

The issue was working on my local LAMP setup vs. uploading to my host. The host wouldn't allow me to dynamically request memory and "frowned upon" editing htaccess data. But, aside from fixing the issue, I was also able to run a lot more transformations on the images besides basic resizing in one shot by breaking them up. Now I'm running base overlays, resizing, color indexing and some other alterations faster than I had expected.

Thanks.