10

I am implementing some image manipulation using great intervention library on Laravel 5. It works fine if image is small, like under 700KB with size lower than 800px wide.

But its not able to handle large size images, I want to upload images as big as 8 MB with 2000px wide.

I have tried classic way of bumping the memory_limit but its not working

ini_set("memory_limit","20M");

Is there any solution which can work without killing the server.

Here is the code of my Upload service. It takes image from Request::file('file') and Resize it to 3 sizes using intervention.

  • Big size which is max width of 2000 px, then a
  • Medium 800px wide
  • Thumb is 200px wide

    public function photo($file)
    {
        $me = Auth::user();
        //user folder for upload
        $userFolder = $me->media_folder;
    
        //Check the folder exist, if not create one
        if($this->setupUsrFolder($userFolder)) {
            //Unique filename for image
            $filename = $this->getUniqueFilename($userFolder);
    
            //Bump the memory to perform the image manipulation
            ini_set("memory_limit","20M");
    
            //Generate thumb, medium, and max_width image
            $img = Image::make($file);
            //big_img
            $big = $img->resize(config('go.img.max_width'), null, function ($constraint) {
                $constraint->aspectRatio();
                $constraint->upsize();
            });
            //Big Image
            $big->save($this->getPhotoPath($filename, $userFolder, 'b_'));
    
            //Medium image
            $med = $big->resize(config('go.img.med_width'), null, function ($constraint) {
                $constraint->aspectRatio();
                $constraint->upsize();
            });
            $med->save($this->getPhotoPath($filename, $userFolder, 'm_'));
    
            //Thumbnail
            $thumb = $med->resize(config('go.img.thumb_width'), null, function ($constraint) {
                $constraint->aspectRatio();
                $constraint->upsize();
            });
            $thumb->save($this->getPhotoPath($filename, $userFolder, 't_'));
    
            return $filename;
        }
    
        return null;
    }
    

Please help me how I can make it more efficient on and fast

Saqueib
  • 3,484
  • 3
  • 33
  • 56
  • 1
    Please try the following, use `$img` for `$med` and `$thumb` as you did with `$big`. After each `->save()`, use `->destroy()`. And `ini_set("memory_limit","20M");` is very low by the way. – user2094178 Jun 30 '15 at 03:18
  • 1
    20971520 bytes is 20M, so how can you be sure setting the memory limit isn't working? – Devon Bessemer Jun 30 '15 at 03:20
  • Thanks @user2094178 let me try `->destroy()` and memory will be 48M, @Devon ya its setting the memory to 20MB but its not working, giving same error. – Saqueib Jun 30 '15 at 03:26
  • @Saqueib...so increase it higher than 20M, default is 128M. – Devon Bessemer Jun 30 '15 at 03:32
  • Thanks @Devon i have set memory to 128m, but now I am getting `imagesx() 19 is not a valid Image resource` after calling `->destroy()` on saving every image – Saqueib Jun 30 '15 at 03:40
  • Seems like a different problem now. So not relevant to this question any longer. – Devon Bessemer Jun 30 '15 at 03:42
  • Ya, although its working without calling `->destory()`, it seem that it is destroying the image object so no other resizing is possible. Thank again for help. – Saqueib Jun 30 '15 at 03:44
  • @user2094178 please help me with this, I think its good idea to release the memory after saving, but its giving error `imagesx() 19 is not a valid Image resource` – Saqueib Jun 30 '15 at 03:45
  • Ok, `->destroy()` also gives me `imagesx() 19` error. Try using `$img` for all instances, get rid of `$big =, $med = and $thumb =`. That should work, if not, do `Image::make` and `->destroy()` for each instance, this worked for me without `imagesx() 19` error. – user2094178 Jun 30 '15 at 16:33
  • So you want me to do `Image::make($file)->resize(2000, null)->save('big.jpg')->resize(800, null)->save('med.jpg')->resize(200, null)->save('thumb.jpg')->destroy()`; or call individually like `Image::make($file)->resize(2000, null)->save('big.jpg')->destroy() ... and others` – Saqueib Jul 01 '15 at 01:53
  • If possible make an answer so i can accept it – Saqueib Jul 01 '15 at 01:55

2 Answers2

11

FWIW, the commented solutions didn't work for me. That is, I couldn't get the following to work for me:

Image::make($file)->resize(2000, null)->save('big.jpg')->destroy();
Image::make($file)->resize(800, null)->save('med.jpg')->destroy();
Image::make($file)->resize(200, null)->save('thumb.jpg')->destroy();

It was still throwing the following error:

Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 16384 bytes) in  
C:\Users\XXX\app\vendor\intervention\image\src\Intervention\Image\Gd\Decoder.php on line 136

This solution worked for me was to change the memory limit as follows:

public function resize() {
    ini_set('memory_limit', '256M');
    // Do your Intervention/image operations...
}

// or...

ini_set('memory_limit', '256M');
Image::make($file)->resize(2000, null)->save('big.jpg');
Image::make($file)->resize(800, null)->save('med.jpg');
Image::make($file)->resize(200, null)->save('thumb.jpg');

This successfully solved the problem.
The reason being:

Resizing images is a very memory consuming task. You can't assume that a 1MB image takes 1MB of memory. Resizing a 3000 x 2000 pixel image to 300 x 200 may take up to 32MB memory for example. Even if the image is under 1MB filesize.
@olivervogel. 2018. Allowed memory size of 134217728 bytes exhausted. [ONLINE] Available at: https://github.com/Intervention/image/issues/567#issuecomment-224230343. [Accessed 14 June 2018].

JustCarty
  • 3,839
  • 5
  • 31
  • 51
2

Just update php.ini file memory_limit to 256M.

memory_limit=256M

I have tried with other memory_limit with 128 and 20. That doesn't work for me. But when I update my memory limit to 256M then the issue solved for me.

In the cpanel, you will find PHP options. From that you need to update the memory limit to:

memory_limit=256M
or
memory_limit=192M
or
memory_limit=368M
or
memory_limit=512M