Muhammad Yasir Amin

Loading websiteโ€ฆ

More from Muhammad Yasir Amin

Build Along With Me

Practical walkthroughs on Laravel, React, APIs and deployment workflows.

Subscribe on YouTube

Laravel 13 Add a Watermark to an Image with Intervention Image 4

๐Ÿ› ๏ธ Laravel Tutorials4 min read

Laravel 13 Add a Watermark to an Image with Intervention Image 4

Muhammad Yasir Amin

Muhammad Yasir Amin

Senior Full Stack Engineerโ€ขNov 12, 2026
Laravel 13 Add a Watermark to an Image with Intervention Image 4

To add a watermark to an image in Laravel 13, decode both the photo and your logo with Intervention Image 4, scale the logo, and place it with $image->insert($logo, 10, 10, Alignment::BOTTOM_RIGHT, 0.5). The last arguments set the offset, the corner and the opacity. This guide shows the method, a reusable service, and how to apply the watermark to uploads.

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

Step 1: Install and prepare the logo

Code
composer require intervention/image

Save your watermark as a PNG with a transparent background, for example resources/images/watermark.png. A PNG keeps the transparent areas, so only the logo shape is drawn on the photo.

Step 2: Understand insert()

The method in Intervention Image 4 has this signature:

PHP
Image::insert(mixed $image, int $x = 0, int $y = 0, string|Alignment $alignment = Alignment::TOP_LEFT, float $transparency = 1)
  • $image is the image to insert: a path, binary data or another image object.
  • $x and $y are offsets from the chosen corner.
  • $alignment is where the image is placed (for example Alignment::BOTTOM_RIGHT).
  • $transparency goes from 0 (invisible) to 1 (opaque).

Step 3: Write a watermark service

JavaScript
<?php

namespace App\Services;

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

class WatermarkService
{
    public function apply(string $sourcePath, string $targetPath): void
    {
        $manager = ImageManager::usingDriver(Driver::class);

        $image = $manager->decode($sourcePath);

        $logoWidth = max(80, (int) ($image->width() * 0.2));

        $watermark = $manager
            ->decode(resource_path('images/watermark.png'))
            ->scale(width: $logoWidth);

        $image->insert($watermark, 20, 20, Alignment::BOTTOM_RIGHT, 0.5);

        $image->save($targetPath);
    }
}

The logo is scaled to 20 percent of the photo width (at least 80 pixels), so it looks right on small and large images. The offset of 20 pixels keeps it away from the edge, and opacity 0.5 makes it visible but not distracting.

Step 4: Watermark an upload

JavaScript
<?php

namespace App\Http\Controllers;

use App\Services\WatermarkService;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Str;

class PhotoController extends Controller
{
    public function store(Request $request, WatermarkService $watermark): RedirectResponse
    {
        $request->validate([
            'photo' => ['required', 'image', 'mimes:jpg,jpeg,png,webp', 'max:8192'],
        ]);

        $name = Str::uuid()->toString().'.jpg';
        $folder = storage_path('app/public/photos');

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

        $watermark->apply($request->file('photo')->getRealPath(), $folder.'/'.$name);

        return back()->with('success', 'Photo saved with watermark.');
    }
}

Saving with a .jpg extension makes Intervention encode the result as JPEG. Use .png or .webp if you prefer those formats. Keep the original upload elsewhere if you may need an unwatermarked version later.

How do I change the watermark position?

Pass another Alignment value:

PHP
$image->insert($watermark, 0, 0, Alignment::CENTER, 0.25);      // faint, centered
$image->insert($watermark, 20, 20, Alignment::TOP_LEFT, 0.6);   // top left

A faint centered watermark is harder to crop out than a corner logo. A corner logo is less intrusive for viewers. Choose based on your goal.

What about text watermarks?

For text, use the text() method with a font file instead of insert(), as described in the tutorial about writing text on images. You can combine both on the same image.

How do I check that it works?

  1. Upload a landscape photo and a portrait photo.
  2. Open the saved files and confirm the logo sits in the bottom right and scales with the image.
  3. Change the opacity to 1 and then to 0.2 to see the difference.

Common mistakes

  • Logo too large: scale it to a share of the photo width instead of using a fixed size.
  • JPEG logo with a white box: use a PNG with transparency.
  • Opacity given as 50: the parameter range is 0 to 1, so use 0.5.
  • Using version 3 methods: use decode() and the manager factory ImageManager::usingDriver().
  • Believing a watermark prevents copying: it discourages casual reuse, but it does not stop determined copying.

FAQ

Can I watermark many images at once?

Yes. Loop over the files and call the service for each. For many files, run the work in a queued job.

Does this work with Imagick?

Yes. Replace the driver import with Intervention\Image\Drivers\Imagick\Driver.

Can the logo come from storage instead of resources?

Yes. decode() accepts a path, so you can point to any readable file, or pass the binary content of a file from a disk.

References

Article Index & Topic Tags
LaravelIntervention-ImageImagesWatermark

YouTube Channel

Build Along With Me

Practical walkthroughs on Laravel, React, APIs and deployment workflows.

Muhammad Yasir Amin
Available for Contracts
Author & Solutions Architect

Senior Full Stack Engineer

Independent Senior Full Stack Engineer working on Laravel, React and Next.js applications, APIs and delivery workflows.

Laravel & PHP ApplicationsReact & Next.js InterfacesREST APIs & IntegrationsDatabase Queries & DebuggingDocker Development WorkflowsClear Scope & Handover
Discuss Your Next Step

What Does Your Application Need Next?

Share your current system, the problem you want to solve and what a useful result looks like. We can identify the right starting point and agree on a practical scope.

Technical Audit

Find the Next Useful Fix

Application Development

Scoped, Reviewable Milestones

Ongoing Support

Agreed Capacity and Priorities

Share your goals, current stack and requirements before the call.