0

I'm trying to upload an image into an application I'm creating. The .png image occupies about 190KB in the file system and the resolution is 2000px wide and 1667 px in height. I have set the memory limit for PHP for 32MB. But when I try to upload this .png image which I believe a lot of the people using my application will do, I'm getting the following error

Allowed memory size of 33554432 bytes exhausted (tried to allocate 13336000 bytes)

Now when I calculated these into say MB I understood that it read

Allowed memory size of 32MB exhausted ( tried to allocate 12.71MB )

So what I don't understand is how come a file which shows a size of 190KB on the file system end up taking up so much memory space? Is it something about how .png files are handled in memory which I don't know about?

Here is the code

private function optimise_image($source_path, $destination_path){
    list($source_image_width, $source_image_height, $source_image_type) = getimagesize($source_path);
    //Using this source path, we'll create a memory instance of the image for processing
    $source_image_ratio = $source_image_width/$source_image_height;
    switch ($source_image_type) {
        case IMAGETYPE_GIF:
            $source_gd_image = imagecreatefromgif($source_path);
            break;
        case IMAGETYPE_JPEG:
            $source_gd_image = imagecreatefromjpeg($source_path);
            break;
        case IMAGETYPE_PNG:
            $source_gd_image = imagecreatefrompng($source_path);
            break;
    }

The error is occuring in imagecreatefrompng(). I load the image here to reduce it's resolution and to set it's quality to optimise storage and bandwidth on viewing.

Upon investigating a bit further, I found that the file is being uploaded and the size of the file on the server is again 190KB. So the piece of code you're seeing is where it's trying to pick up the file again for processing. Before this there's no where in the process where the file is being loaded into memory once and then left there without being destroyed ( which I thought was what would have been happening )

If there is any more information you may require, do ask I and I shall try and answer accordingly.

Thanks in advance :)

Prathamesh Datar
  • 375
  • 1
  • 4
  • 20
  • 2
    Post some code to get better idea on that. – Rikesh Jul 12 '13 at 13:21
  • set the memory size using ini_set('memory_limit','200M') like this – Sundar Jul 12 '13 at 13:21
  • @Sundar Why would you need 200M for a 190Kb image? – tlenss Jul 12 '13 at 13:25
  • You need to increase PHP's memory limit inside your php.ini file. – qJake Jul 12 '13 at 13:26
  • read this post http://stackoverflow.com/questions/15024443/allowed-memory-size-exhausted – Nanhe Kumar Jul 12 '13 at 13:34
  • You have to clear your GC this may holds the previous cached memory. If you set maximum this work without issues in-future also. but find a way to clear your cached memory before and after creating the image – Sundar Jul 12 '13 at 13:34
  • @SpikeX - I do understand that I need to increase the memory limit. I think the accepted norm is around 128MB for php. But I want to understand why is 32MB insufficient to handle the processing of a 190KB png file. Is it something to do with the resolution of the image? I've been testing the upload with files with same or even sometimes larger sizes on disk ( but lower resolution ) and they got processed without any problems. – Prathamesh Datar Jul 12 '13 at 13:34
  • It tried to allocate 12MB when processing your image. The size of your image matters, but what also matters is the size of the image processing libraries and all of the other stuff behind the scenes of PHP. The memory limit is for *everything PHP has to load into memory*, not just your own images/code/whatever. – qJake Jul 12 '13 at 13:48
  • 1
    Hi @SpikeX - Yep. You're right. I think the post below answered a fundamental knowledge gap which I had ( which was why ~12MB was being allocated for a 190KB file ) .. And yes, 12MB coupled with other php related memory usage would have rendered 32MB insufficient .. – Prathamesh Datar Jul 12 '13 at 13:53

1 Answers1

2

image-width x image-height x 4 bytes (32bit) per pixel is needed just for the imagecreatefrompng / imagecreatefromjpeg

So that's roughly 12MB in your case

That leaves just 20MB for the GD lib and other PHP processes.

Tom Lous
  • 2,819
  • 2
  • 25
  • 46
  • Yep. That's the answer I was looking for. It's very interesting to know how it all boils down to bytes and bits. Thanks for giving an answer to understand. So I guess the 190KB is the size of the file once compressed on the file system .. Another clue which I thought would be related to the resolution was that every time I opened the file, my fan would just whizz for a short time which was odd for such a small file ( and it took longer to open that file as well ) .. Thanks again :) – Prathamesh Datar Jul 12 '13 at 13:42