Is laravel image intervention a good way to compress user uploaded images?
Asked Answered
G

6

7

I was checking out this laravel library to compress user uploaded images.http://image.intervention.io/

I was wondering if this is a good idea for user uploaded images (for profilepictures)? What if the user uploads a picture with a size of 1400x600 and it will be resized to 200x200? Will it be a stretched out image?

Gist answered 25/5, 2016 at 7:18 Comment(0)
Z
6

Yes, it will be stretched. You want to try fit() method:

Combine cropping and resizing to format image in a smart way. The method will find the best fitting aspect ratio of your given width and height on the current image automatically, cut it out and resize it to the given dimension.

// crop the best fitting 1:1 ratio (200x200) and resize to 200x200 pixel
$img->fit(200);
Zipah answered 25/5, 2016 at 7:28 Comment(1)
what about dpi of an image? @Alexey MezeninCrossindex
S
4

Intervention is great for handling just this. Here's a quick code snippet to get you going in the right direction:

$resize_to = $this->sizes(); //some arbitrary array

//generate our custom image sizes
foreach ($resize_to as $idx => $width) {
    if ($img = Image::make($file->getRealPath())) {
        $img->resize(width, null, function ($constraint) {
            $constraint->aspectRatio();
            $constraint->upsize();
        });
        $img->encode($encoding_options);
        $img->save($path);
    }
}

In the above we're looping over some array of widths that we want to have images resized to. Pay attention to the $constraints that we've declared below. The aspectRatio() ensures the image never loses it's aspect ratio. The ->upsize() prevents images from being upsized and losing the resolution.

What you're asking for - resizing a 1400x600 image to 200x200 is unreasonable.

Instead, you should just resize to one dimension and make sure that your HTML can account for the rest. For example, in the above we only observe widths. So we'll assume in your $this->sizes() array, one of them is 200. But the image was a different ratio, so it didn't produce a 200x200, it produced a 200x150. Handle that in the HTML by using a flexbox super easily:

<div class="flex-box-centered">
   <img class="flex-img" src="..."/>
</div>

And the CSS:

.flex-box-centered {
    display:flex;
    width:200px;
    height:200px;
    justify-content:center;
    align-items:center;
    background:#fff;
}

.flex-img {
    display:flex;
    width:100%;
    height:auto;
}

And here's a jsfiddle illustrating this concept

Sikorski answered 25/5, 2016 at 7:28 Comment(0)
A
1

When you have loaded image in $image as Intervention\Image\Image you can easily do it like this:

// $height and $width are your max values
if ($image->width < $image->height) {
    $image->resize(null, $height, true, false);
} else {
    $image->resize($width, null, true, false);
}

which will resize your image in the right way.

Ardeha answered 25/5, 2016 at 7:32 Comment(0)
L
1

well, yes it is better option. Since Image Intervention uses Imagick in the background. I would recommend you to use Image Intervention. You can also compress images when you saving them.

// open and resize an image file
$img = Image::make('public/foo.jpg')->resize(300, 200);

// save file as jpg with medium quality
$img->save('public/bar.jpg', 60); 

image quality ranges from 0 (poor quality, small file) to 100 (best quality, big file).

Lath answered 11/7, 2017 at 8:16 Comment(0)
A
1

composer require intervention/image

// config/app.php

return [
    ......
    $provides => [
        ......
        ......,
        'Intervention\Image\ImageServiceProvider'
    ],
    $aliases => [
        .....
        .....,
        'Image' => 'Intervention\Image\Facades\Image'
    ]
]

/* Controller Code

    /*With Image Compression*/

            $image = $request->file('profile_image');
            $fileExtension   = strtolower($image->getClientOriginalExtension()); 
            $file_name       = sha1(uniqid().$image.uniqid()).'.'.$fileExtension;
            $destinationPath = 'uploads/profile_image/';
                $img = Image::make($image->getRealPath());
                $img->resize(140, 140, function ($constraint) {
                $constraint->aspectRatio();
            })->save($destinationPath.$file_name);

    /*End With Image Compression*/    
Antipersonnel answered 9/11, 2017 at 7:30 Comment(1)
good job thanx.Oaten
C
0

I get the original picture then I resize to 50% which keeps a better ratio. So it doesn't look bad to the user.

$imageDimensions = getimagesize($image);
$width = $imageDimensions[0];
$height = $imageDimensions[1];
$new_width = $imageDimensions[0] * 0.5;
$new_height = ceil($height * ($new_width / $width));
$image = Image::make($image)->resize($new_width, $new_height);

I first get the normal dimensions then I make a calculation to resize it properly.

Cilicia answered 18/3, 2021 at 14:47 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.