Dev.to WebDev πŸ›  Dev πŸ‘ 0 πŸ“– 3 min read

How to Compress Image Size in Laravel 13: Resize and Re-encode Uploads

To compress an image in Laravel 13, resize it to a sensible maximum width with scaleDown() and re-encode it with a lower quality value, for example $image->save($path, quality: 75). Most of the size saving comes from red

To compress an image in Laravel 13, resize it to a sensible maximum width with scaleDown() and re-encode it with a lower quality value, for example $image->save($path, quality: 75). Most of the size saving comes from reducing the pixel dimensions, and the rest from the quality setting and from switching to a format such as WebP. This guide shows each step with Intervention Image 4.

Targets: Laravel 13 (PHP 8.3 to 8.5), intervention/image 4 and the GD or Imagick extension.

Why are uploaded images so large?

A phone photo is often 4000 pixels wide and several megabytes. A web page rarely shows it wider than 1600 pixels. Serving the original wastes bandwidth and slows the page, which hurts users and search rankings. Compressing at upload time fixes this once.

Step 1: Install Intervention Image

composer require intervention/image

Step 2: Scale down and save with quality

use Intervention\Image\Drivers\Gd\Driver;
use Intervention\Image\ImageManager;

$manager = ImageManager::usingDriver(Driver::class);

$manager->decode($sourcePath)
    ->scaleDown(width: 1600)
    ->save($targetPath, quality: 75);

scaleDown() keeps the aspect ratio and only reduces the size. It never enlarges a small image, which would only make it blurry. save() picks the format from the extension of the target path and passes quality to the encoder. For JPEG, values between 70 and 85 are a common balance between size and appearance, but check your own images.

Step 3: Compress uploads in a service

<?php

namespace App\Services;

use Illuminate\Http\UploadedFile;
use Illuminate\Support\Str;
use Intervention\Image\Drivers\Gd\Driver;
use Intervention\Image\ImageManager;

class ImageCompressor
{
    public function store(UploadedFile $file, string $folder = 'photos', int $maxWidth = 1600, int $quality = 75): array
    {
        $directory = storage_path('app/public/'.$folder);

        if (! is_dir($directory)) {
            mkdir($directory, 0775, true);
        }

        $name = Str::uuid()->toString().'.webp';
        $target = $directory.'/'.$name;

        ImageManager::usingDriver(Driver::class)
            ->decode($file->getRealPath())
            ->scaleDown(width: $maxWidth)
            ->save($target, quality: $quality);

        return [
            'path' => $folder.'/'.$name,
            'original_kb' => (int) round($file->getSize() / 1024),
            'compressed_kb' => (int) round(filesize($target) / 1024),
        ];
    }
}

This version writes WebP files. WebP is supported by all current major browsers and is usually smaller than JPEG at similar quality. Use a .jpg extension instead if you must support very old software.

Step 4: Use it in a controller

public function store(Request $request, ImageCompressor $compressor)
{
    $request->validate([
        'photo' => ['required', 'image', 'mimes:jpg,jpeg,png,webp', 'max:10240'],
    ]);

    $result = $compressor->store($request->file('photo'));

    return back()->with('success', "Saved. {$result['original_kb']} KB became {$result['compressed_kb']} KB.");
}

Should I strip metadata?

Photos contain EXIF data such as camera model and sometimes GPS location. The save() method accepts encoder options that depend on the format, and the documentation lists strip as an option. Removing metadata makes the file smaller and protects privacy. Check the encoder options for your format in the Intervention documentation, and test that your chosen option is applied.

Which quality value is right?

  • 85 and above: near the original look, larger files. Good for photography portfolios.
  • 70 to 80: a good default for most websites.
  • Below 60: visible artifacts, only for small previews.

These ranges are rules of thumb. Try your own images at two or three values and look at the output.

How do I check the result?

  1. Upload a large photo (several megabytes).
  2. Read the message with the original and compressed sizes.
  3. Open the saved image and compare it with the original at normal viewing size.

Common mistakes

  • Only lowering quality: reduce the dimensions first, because pixels matter most.
  • Enlarging small images: use scaleDown(), not scale(), for limits.
  • Compressing an already compressed image repeatedly: quality drops each time. Process the original once.
  • Running heavy jobs in the request: for many or very large images, use a queued job.
  • Forgetting the extension decides the format: the target path extension picks the encoder.

FAQ

Is GD or Imagick better for compression?

Both work. Imagick is usually faster for large images and offers more format options.

Can I keep the original file too?

Yes. Store the original on a private disk and the compressed version on the public disk.

What about PNG files?

PNG is lossless, so the quality value has less effect. For photos, convert to WebP or JPEG. Keep PNG for graphics with sharp edges or transparency.

References

Originally published on yasiramin.dev.

πŸ“° Read the original article on Dev.to WebDev

Originally published by Dev.to WebDev. Aggregated on AIWithGhost for educational purposes β€” full credit and traffic to the original publisher.