HomeDocsPHP guide
PHP guide · Images

How to Watermark Images in PHP

Brand your images in Laravel, Symfony, or vanilla PHP without battling the infamous 'Allowed memory size exhausted' fatal error.

Writing PHP code with API Watermark

Beating PHP's Memory Constraints

If you've ever tried to watermark a 10MB JPEG taken from a modern iPhone using standard PHP `imagecreatefromjpeg()` (GD) or `Imagick`, you likely hit an `Allowed memory size of X bytes exhausted` error. Uncompressing a 10MB JPEG into memory takes over 150MB of RAM, instantly killing standard Apache/PHP-FPM worker instances. Offloading to an API solves this instantly.

Step by step

Drop this into your project today

  1. 1

    1. Skip Local Processing

    Instead of moving the `$_FILES` temporary upload to your server to process it locally, stream it directly to our API.

  2. 2

    2. Configure the HTTP Client

    Use Laravel's HTTP Client, Guzzle, or standard `curl_init()` to send the file and your visual configurations.

  3. 3

    3. Save the Output

    Download the returned string directly to your public storage or AWS S3 bucket configured in your PHP app.

Watermarking with Guzzle (PHP)
<?php
require 'vendor/autoload.php';

use GuzzleHttp\Client;

$client = new Client();
$apiKey = getenv('API_WATERMARK_KEY');

try {
    $response = $client->request('POST', 'https://apiwatermark.com/api/watermark', [
        'headers' => [
            'Authorization' => 'Bearer ' . $apiKey,
        ],
        'multipart' => [
            [
                'name'     => 'image',
                'contents' => fopen('/path/to/uploaded/file.jpg', 'r')
            ],
            [
                'name'     => 'text',
                'contents' => '© Copyright 2026'
            ],
            [
                'name'     => 'position',
                'contents' => 'center'
            ]
        ]
    ]);

        file_put_contents('/path/to/output/watermarked-file.jpg', $response->getBody()->getContents());

    $data = json_decode($response->getBody(), true);
    
    // Output URL from API
    echo "Secured Image: " . $data['output_url'];

} catch (\GuzzleHttp\Exception\GuzzleException $e) {
    echo "Error processing image: " . $e->getMessage();
}
?>

FAQ

Developer questions

Is this faster than using Imagick locally?

+
In almost all cases, yes. Our clustered network utilizes dedicated hardware specifically tuned for batch media operations, bypassing slow standard server CPUs.

Can I use an image logo instead of text?

+
Yes, you can pass a URL to your PNG logo file via the `watermark_url` parameter instead of the `text` string.

Watermark images from PHP today

Stop maintaining PHP media pipelines. Free tier covers 100 calls a month.