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

How to Add Text to an Image in Laravel 13 with Intervention Image 4

๐Ÿ› ๏ธ Laravel Tutorials4 min read

How to Add Text to an Image in Laravel 13 with Intervention Image 4

Muhammad Yasir Amin

Muhammad Yasir Amin

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

To add text to an image in Laravel 13, install intervention/image, decode the image with an ImageManager, call $image->text() with the text, an x and a y position and a font callback, and then save or return the result. The callback sets the font file, size, color, stroke and alignment. This guide uses Intervention Image 4, whose API differs from version 3, and shows each option with working code.

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

Step 1: Install the package

Code
composer require intervention/image

You need an image extension: GD is included in most PHP installs, Imagick is faster for large images. Check with php -m.

Step 2: Add a font file

Pick a font file you are allowed to use (for example from a free font library) and put it in your project, such as resources/fonts/Roboto-Bold.ttf. Setting a font file makes the text look the same on every server instead of depending on the fonts installed on the machine.

Step 3: Write text on an image

JavaScript
<?php

namespace App\Services;

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

class ImageTextService
{
    public function write(string $sourcePath, string $targetPath, string $text): void
    {
        $manager = ImageManager::usingDriver(Driver::class);

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

        $image->text($text, (int) ($image->width() / 2), (int) ($image->height() - 60), function (FontFactory $font) {
            $font->filepath(resource_path('fonts/Roboto-Bold.ttf'));
            $font->size(48);
            $font->color('ffffff');
            $font->stroke('000000', 2);
            $font->align(Alignment::CENTER, Alignment::BOTTOM);
        });

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

The first three arguments of text() are the string and the x and y coordinates of the base point. Here the point is the horizontal center near the bottom of the image, and align() centers the text around that point.

What do the font options do?

  • filepath() sets the path of the font file.
  • size() sets the font size (the default is 12).
  • color() sets the text color in any supported color format, such as 'fff', 'ffffff' or 'rgb(255, 255, 255)'.
  • stroke() adds an outline with a color and a width from 0 to 10. When stroke is used, the text and stroke colors must be fully opaque.
  • align() sets horizontal and vertical alignment relative to the point you passed.
  • lineHeight(), angle() and wrap() control line spacing, rotation and the maximum width in pixels before text wraps to a new line.

Step 4: Use it from a controller

JavaScript
<?php

namespace App\Http\Controllers;

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

class ImageTextController extends Controller
{
    public function store(Request $request, ImageTextService $service): RedirectResponse
    {
        $data = $request->validate([
            'image' => ['required', 'image', 'mimes:jpg,jpeg,png,webp', 'max:5120'],
            'text' => ['required', 'string', 'max:80'],
        ]);

        $name = Str::uuid()->toString().'.'.$request->file('image')->extension();
        $target = storage_path('app/public/watermarked/'.$name);

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

        $service->write($request->file('image')->getRealPath(), $target, $data['text']);

        return back()->with('success', 'Saved as storage/watermarked/'.$name);
    }
}

The save() method needs an existing folder, so the controller creates it first. The format of the saved file follows the file extension in the target path.

How do I return the image without saving it?

Encode it and send it in the response:

JavaScript
use Intervention\Image\Format;

$encoded = $image->encodeUsingFormat(Format::JPEG, quality: 85);

return response((string) $encoded, 200, ['Content-Type' => 'image/jpeg']);

How do I check the result?

  1. Upload a photo with the text "Hello Laravel".
  2. Open the saved file and confirm the text appears at the bottom center with an outline.
  3. Change the size, color and alignment values and repeat to see their effect.

Common mistakes

  • Using the version 3 API: version 4 creates the manager with ImageManager::usingDriver(Driver::class) and loads files with decode(), not read().
  • Wrong font path: the text silently looks wrong or an error occurs. Check the file exists.
  • Text too long for the image: use wrap() or reduce the size.
  • Missing target folder: save() does not create folders.
  • Trusting user file names: generate a new name as the controller does.

FAQ

Does this work with the Imagick driver?

Yes. Change the import to Intervention\Image\Drivers\Imagick\Driver. The text methods stay the same.

Can I add text to a transparent PNG?

Yes, but if you use stroke(), remember the text and stroke colors must be fully opaque.

Is there a Laravel integration package?

Yes, intervention/image-laravel adds a facade and a config file. The core API above is the same.

References

Article Index & Topic Tags
LaravelPhpIntervention-ImageImages

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.