Laravel 10 Image Compression And Optimization Guide 2024

Laravel Image Compression Project in 10 Minutes

Last Updated On - August 2nd, 2024 Published On - Feb 27, 2023

Overview

Laravel Image compression project is used to compress any image to a smaller size while maintaining the quality of the image. It is generally used to make images of almost the same resolution with smaller sizes so that the web page looks good and loads quickly as the more prominent images take time to load.


Architecture

For this project, I will be using the Laravel PHP framework as it provides a robust set of tools and features for building web applications. I am going to use a package spatie/image-optimizer which is helpful in image compression.

To store the images, I will be saving them in the project directory itself but you can use Amazon S3, which is a scalable and secure cloud storage service. Using S3 will allow you to easily store and retrieve images without having to worry about managing your own storage infrastructure.

To handle the user interface, I will be using Bootstrap, a popular front-end framework that provides a set of pre-designed UI components that we can use to build a responsive and user-friendly interface.


Steps To Implement

  • Create a Laravel project using the following command:
composer create-project --prefer-dist laravel/laravel image-compress-project
  • Install the spatie/image-optimizer Image package using Composer:
composer require spatie/image-optimizer

Optimization tools

  • The package will use these optimizers if they are present in your system:
  • JpegOptim
  • Optipng
  • Pngquant 2
  • SVGO 1
  • Gifsicle
  • cwebp
  • Here’s how to install all the optimizers on Ubuntu:
sudo apt-get install jpegoptim
sudo apt-get install optipng
sudo apt-get install pngquant
sudo npm install -g svgo@1.3.2
sudo apt-get install gifsicle
sudo apt-get install webp
  • And here’s how to install the binaries on MacOS (using Homebrew):
brew install jpegoptim
brew install optipng
brew install pngquant
npm install -g svgo@1.3.2
brew install gifsicle
brew install webp
  • And here’s how to install the binaries on Fedora/RHEL/CentOS:
sudo dnf install epel-release
sudo dnf install jpegoptim
sudo dnf install optipng
sudo dnf install pngquant
sudo npm install -g svgo@1.3.2
sudo dnf install gifsicle
sudo dnf install libwebp-tools

Also Read: Learn How to Use the Slack API to Post Messages in Slack Channel Using Laravel


  • Create a controller to handle the image compression logic using the following command:
php artisan make:controller CompressController
  • In the CompressController class, create 2 methods index() and compress() to load the upload image form and to resize & save the image respectively:
use Exception;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
use Spatie\ImageOptimizer\OptimizerChainFactory;

class CompressController extends Controller
{
    public function index()
    {
        return view('image-optimizer');
    }

    public function compress(Request $request)
    {
       // Validate the image for acceptable image formats and max upload size(Max upto 5MB)
        $validator = Validator::make(
            $request->all(),
            [
                'image' => 'required|file|mimes:jpeg,jpg,png,gif,svg,webp|max:5120',
            ]
        );
        if($validator->fails()){
            return redirect()->back()->withErrors($validator->errors())->withInput();
        }

        try{
            // Get the uploaded image from the request
            $image = $request->file('image');

            // Generate a unique filename for the uploaded image
            $imagename = time().'.'.$image->getClientOriginalExtension();
            
            // Set the path to save the original image
            $imagepath = public_path('/images/');
            
            // Set the path to save the compressed image
            $pathToOutput = public_path('/optimizedImage/');

            // Save the original image
            $image->move($imagepath, $imagename);

            // Compress image and save it to optimizedImage path using Spatie's OptimizerChainFactory 
            $optimizerChain = OptimizerChainFactory::create();
            $optimizerChain->optimize($imagepath.$imagename,$pathToOutput.$imagename);

            // Delete the original image
            unlink($imagepath.$imagename);

            // Redirect back to image uploader with success message.
            return back()->with('success', 'Image compressed successfully.');
        }
        catch(Exception $e)
        {
            // Redirect back to image uploader with error message.
            $error = 'Opps! something goes wrong. Please try later';
            return redirect()->back()->with('error',$error)->withInput();
        }
    }
}

Let’s break down each part of the compress() function:

  1. The compress() function takes a Request object as its argument. This object contains the uploaded image that we want to compress.
  2. We get the uploaded image from the request using the file() method.
  3. We generate a unique filename for the uploaded image using the current timestamp and the original file extension.
  4. We set the path where we are going to save the original image. In this case, we save it to the public/images directory.
  5. We set the path where we want to save the compressed image. In this case, we save it to the public/optimizedImage directory.
  6. We use the spatie/ImageOptimizer package to compress the image. We first create an instance of OptimizerChainFactory::create(). By using this instance, compress and save the original image. Finally, we remove the original image(uncompressed one) from its original path.
  7. If the image is compressed successfully, we return a success message to the user.

  • Create image-optimizer.blade.php file inside resources->views. Create a form to upload the image:
<div class="container" style="margin-top: 50px;">
    @if (session('success'))
        <div class="alert alert-success">
            {{ session('success') }}
        </div>
    @endif
    <h2>Compress JPEG</h2>
    <form action="{{ url('compress') }}" method="post" enctype="multipart/form-data">
        @csrf
        <div class="form-group">
            <input type="file" name="image" class="form-control" required>
        </div>
        <button type="submit" class="btn btn-primary">Compress</button>
    </form>
</div>
  • Add the following routes in routes/web.php:
// Show image upload form
Route::get('/image-optimizer', [ImageController::class, 'index']);
// Compress and save image in folder
Route::post('/compress', [ImageController::class, 'compress']);
  • Run the project using the following command:
php artisan serve

This implementation will allow us to generate a newly resized image and store it in the thumbnail folder.


Also Read: How To Setup Real-Time Synchronization using WebSocket Connection with Laravel 11, Pusher, & Angular 18?


Assumptions

  • For this project, I am assuming that the images being uploaded are not too large for the server to handle, and that we are only concerned with resizing images that are within a reasonable size range. If we need to resize very large images, we may need to consider using a distributed image processing system such as Apache Spark or Apache Flink.
  • The target server is running PHP 7.4 or higher.

Also Read: Create Short URL Hashing & Tracking Project in 10 Minutes: Step By Step Guide


Deployment

Assuming you have a server with PHP and a web server (such as Apache or Nginx) installed, you can deploy the Image resizing project using the following steps:

  1. Copy the contents of the image-resizing directory to your server.
  2. Configure your web server to serve the contents of the public directory as the document root.
  3. Set the necessary environment variables on the server.


FAQs

Website loading slow because of slow images?

Yes! Large images can significantly slow down your website. This guide explains how to use Laravel to compress images, making your website load faster and offering a better user experience for visitors.

Mobile website slow? Try image optimization!

Absolutely! Image optimization is crucial for mobile websites. This guide shows you how to compress images using Laravel, ensuring your website loads quickly on all devices, including mobiles.

Does image compression affect quality?

Yes, but with the right techniques, the impact can be minimal. This guide explains how to compress images in Laravel while maintaining a good balance between quality and size.

Are there free image compression tools available?

Yes, there are many free image compression tools online. However, integrating compression directly into your website using Laravel offers more control and security.

How can I implement image compression on my website myself?

This guide provides a step-by-step explanation of how to implement image compression in your Laravel project. No prior experience is required, and the code examples are easy to follow.

Will this method work for my existing images?

Yes! This method can be used to compress both new and existing images on your website. You can compress them in bulk or one by one, depending on your needs.

Will the quality difference in compressed images be noticeable?

In most cases, the quality difference in compressed images won’t be noticeable to the naked eye. This guide shows you how to achieve optimal compression with minimal quality loss.

Can image compression improve my SEO ranking?

Yes! Faster loading websites tend to rank higher in search results. By compressing images and improving website speed, you can potentially boost your SEO ranking.



TODO Next

  • Resize & C the image to Medium size i.e. 1024px width and use this image to further resize it to thumbnail size i.e. 240px

Conclusion

This blog post has explored image compression techniques and explained how to implement them in your Laravel project. By optimizing images, you can significantly improve website loading speed, enhance user experience, and potentially benefit your SEO ranking.