www.webdeveloper.com
Results 1 to 7 of 7

Thread: imagecreatefromjpeg is eating memory

  1. #1
    Join Date
    Mar 2008
    Posts
    175

    imagecreatefromjpeg is eating memory

    I have some code to handle rather large sized images (1-2MB). It works on most images, and even some large ones that are gifs, but when it comes to large jpegs and when I try to open them with imagecreatefromjpeg - my code just plain stops. The error is "PHP Fatal error: Allowed memory size of 31457280 bytes exhausted (tried to allocate 10240 bytes)"

    I am setting ini_set("memory_limit","30M") which I believe is even beyond the scope of memory allocation allowed by my php.ini. Anyway, that is a huge amount of memory. What am I doing to create so much? Just before the imagecreatefromjpeg is called, I do $mem = memory_get_usage() to see my usage and its only 10k!

    Any ideas? My code is huge but I could post chunks if that would help.

  2. #2
    Join Date
    Aug 2004
    Location
    Ankh-Morpork
    Posts
    19,615
    When you create an image object using the image functions, it is stored in memory as a bitmap, not as the compressed version stored in the jpeg/gif/png file. It will therefore require more memory than the image file from which it was created, usually significantly more in the case of JPEGs, as they are generally highly compressed.

    For instance, I just ran this quick test on my PC:
    PHP Code:
    <?php
    $jpegs 
    glob('*.jpg');
    foreach(
    $jpegs as $file)
    {
       
    $size filesize($file);
       
    $before memory_get_usage();
       
    $img imagecreatefromjpeg($file);
       
    $after memory_get_usage();
       
    printf("%s: %d, image: %d<br>\n"$file$size$after $before);
       
    imagedestroy($img);
    }
    ?>
    With just one jpeg image in that directory, I got this result:
    Code:
    rmnp8.jpg: 87863, image: 1555104
    "Please give us a simple answer, so that we don't have to think, because if we think, we might find answers that don't fit the way we want the world to be."
    ~ Terry Pratchett in Nation

    eBookworm.us

  3. #3
    Join Date
    Mar 2008
    Posts
    175
    That is intriguing, however it doesn't account for the massive amount of memory this thing is eating up. My memory_limit is 16MB as set by the php.ini (which my server doesn't let increase anymore) but I have my script set to ini_set('memory_limit','30M') (not sure if that overrides memory_limit). With a 1.5MB jpeg, the error is: PHP Fatal error: Allowed memory size of 31457280 bytes exhausted (tried to allocate 10240 bytes). If I were to ini_set the memory down to 20M, i'd get a similar error but with the 20M.

    I can never get the 'memory_get_usage()' to show me these huge numbers either. It's just plain weird! Here is some of my code. Maybe I need to imagedestroy or something? Basically, I am taking an attachment from an email, saving it locally, then opening it again for resizing.

    PHP Code:
                     $attachment = array(); 
                    for (
    $y 0$y<2$y++) {
                        
    $attachment[] = array("filedata" => imap_fetchbody($mbox$msgno2));
                    } 

                    
    $server_path "/vservers/wheredidshegetit/htdocs/"
                    
    $image_path "emailed_images/";   
                                    
                    
    // make a unique filename for the uploaded file
                    
    $count 1;
                    while(
    file_exists($filename $server_path.$image_path.$count.'-'.$file))
                    {
                           
    $count++;
                    }        
                    
    $fp=fopen("$filename",'w+');     
                    
    fwrite ($fpimap_base64($attachment[1]['filedata'])); 
                    
    fclose($fp); 
                    echo 
    "...saved attachment to server..";
                    
    // change permissions on new file so it can be accessed via the web
                    
    chmod ($filename0745) or error('CMOD failed. Try again later.');        
                
    ///////////////////////// process uploaded image to achieve standard size
                    
    echo "...reopening file...";
                    
    $image =@imagecreatefromjpeg($filename); 
    The last line is where I get my fatal error. I am still really stumped. It seems like I have a huge memory leak somewhere. What is even worse, is that this is one of two very similar scripts and this one works more often than the other which is driven by a user uploaded image, not one from email.

  4. #4
    Join Date
    Mar 2008
    Posts
    175
    I tested your code. The results:
    1-21 Apr 08 NYC Lionel 368.jpg: 15726, image: 795232
    1-4 May 08 Lionel NYC 001.jpg: 21050, image: 581952
    1-4 May 08 Lionel NYC 014.jpg: 494890, image: 10993168
    1-4 May 08 Lionel NYC 018.jpg: 552507, image: 10952176

    Fatal error: Allowed memory size of 16777216 bytes exhausted (tried to allocate 10240 bytes) in /vservers/wheredidshegetit/htdocs/uploaded_images/check.php on line 11

    The error occurred when I hit an image of 2MB. I never would have believed it if I didn't see it for myself, but damn, a 2MB jpeg really turns into over 16MB of bmp?!?!?!? This is blowing my mind.

  5. #5
    Join Date
    Aug 2004
    Location
    Ankh-Morpork
    Posts
    19,615
    Basically, you can figure that the memory for a 24-bit color bitmap will be the width times the height in pixels, multiplied by the color depth. (Actually, I'm not sure if it's 24 or 32 bits for the PHP true-color images). I found one 1800 x 1200 JPEG on my PC that only needs 1,182KB bytes, but when I opened it in Windows Paint and saved it as a 24-bit bitmap image, sure enough, it uses 6,329KB, which is pretty close to what you get for 1800 * 1200 * 24 / 8.

    Anyway, you definitely want to imagedestroy any image as soon as you are done with it.

    Possibly you could look into using the Imagick class, as it may possibly be more efficient in how it utilizes memory, but I do not know if that is true or not, just hopeful guessing on my part.
    "Please give us a simple answer, so that we don't have to think, because if we think, we might find answers that don't fit the way we want the world to be."
    ~ Terry Pratchett in Nation

    eBookworm.us

  6. #6
    Join Date
    Mar 2008
    Posts
    175
    Thanks. Looks like I just have to beg my host for more memory.

  7. #7
    Join Date
    Apr 2009
    Posts
    1

    Example of memory usage

    Hi,

    I ran into this same problem yesterday. Turns out imagecreatefromjpeg really does inflate memory usage. I was just trying to create a thumbnail from a larger JPEG file. The JPEG was about 4.0MB, and here's the memory report after each step of the process:

    Memory Usage before imagecreatetruecolor: 0.18700408935547 MB
    Memory Usage after imagecreatetruecolor: 0.27689361572266 MB
    Memory Usage after imagecreatefromjpeg: 38.44059753418 MB
    Memory Usage after imagecopyresampled: 38.440620422363 MB
    Memory Usage after imagejpeg: 38.440620422363 MB
    Memory Usage after imagedestroy source: 0.27706146240234 MB
    Memory Usage after imagedestroy tn: 0.20426940917969 MB

    I was as surprised as a lot of people to see this. I can only imagine what kind of havoc this must cause if you're attempting to manipulate images from a half-decent DSLR with a high color depth and a 8+MP sensor!!

    - Andrew

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
HTML5 Development Center



Recent Articles