DEV Community

Cover image for Watermarking Images and Auto-Correcting Sideways Photos with One API Call
PDF4me
PDF4me

Posted on • Edited on

Watermarking Images and Auto-Correcting Sideways Photos with One API Call

Somebody on your team is opening an image editor to stamp a logo onto a batch of product photos. Somebody else, a few tabs over, is manually rotating a stack of scanned receipts that came in sideways from a phone camera. Neither person thinks of the other's task as related to their own, but structurally they're the same job: send an image in, get a modified image back, repeat it a thousand times without touching a mouse.

Below are three PDF4me image API endpoints that cover both problems, with working Python samples for each, verified against the live parameter tables and the base URL from the Connect to PDF4me API guide.

Stamping a logo onto a photo

Add Image Watermark overlays one image, typically a logo or brand mark, onto another. This is compositing, not PDF-page watermarking: control over position, opacity, and rotation is built into the request.

import requests
import base64

api_key = "YOUR_API_KEY"
base_url = "https://api.pdf4me.com"
endpoint = "/api/v2/AddImageWatermarkToImage"

with open("product-photo.jpg", "rb") as f:
    doc_content = base64.b64encode(f.read()).decode("utf-8")

with open("logo.png", "rb") as f:
    watermark_content = base64.b64encode(f.read()).decode("utf-8")

payload = {
    "docName": "product-photo.jpg",
    "docContent": doc_content,
    "WatermarkFileName": "logo.png",
    "WatermarkFileContent": watermark_content,
    "Position": "bottomright",
    "Opacity": 0.6,
    "PositionX": 0,
    "PositionY": 0,
    "Rotation": 0
}

headers = {
    "Content-Type": "application/json",
    "Authorization": api_key
}

response = requests.post(base_url + endpoint, json=payload, headers=headers)

if response.status_code == 200:
    with open("watermarked-photo.jpg", "wb") as f:
        f.write(response.content)
else:
    print(response.status_code, response.text)
Enter fullscreen mode Exit fullscreen mode

Position accepts topright, topleft, bottomright, bottomleft, centralhorizontal, diagonal, centralvertical, or custom (paired with PositionX/PositionY). The watermark asset itself is usually fixed, one logo file reused across a whole batch, so this is a parameterized call, not a design decision.

Same operation, no-code: Make's Add Image Watermark to Image, Zapier's Add Image Watermark To Image, n8n's Add Image Watermark To Image node. The interactive API Tester runs the call against a real image in the browser if you want to see placement before wiring anything.

Stamping text instead of a logo

Not every watermark is a static image. A case number, a capture date, a "confidential" label: these are generated per file, which is exactly what a static overlay image can't do. Add Text Watermark controls font, size, color, and opacity through the request itself.

import requests
import base64

api_key = "YOUR_API_KEY"
base_url = "https://api.pdf4me.com"
endpoint = "/api/v2/AddTextWatermarkToImage"

with open("delivery-photo.jpg", "rb") as f:
    doc_content = base64.b64encode(f.read()).decode("utf-8")

payload = {
    "docName": "delivery-photo.jpg",
    "docContent": doc_content,
    "WatermarkText": "CASE-4471",
    "TextPosition": "bottomleft",
    "TextFontFamily": "Arial",
    "TextFontSize": 24,
    "TextColour": "#ffffff",
    "IsBold": True,
    "IsUnderline": False,
    "IsItalic": False,
    "Opacity": 0.9,
    "RotationAngle": 0,
    "PositionX": 0,
    "PositionY": 0
}

headers = {
    "Content-Type": "application/json",
    "Authorization": api_key
}

response = requests.post(base_url + endpoint, json=payload, headers=headers)
Enter fullscreen mode Exit fullscreen mode

WatermarkText is the one field that makes this dynamic: pull it from a spreadsheet row, a timestamp, or a record in whatever system triggered the call.

No-code equivalents: Make's Add Text Watermark to Image, Zapier's Add Text Watermark To Image, n8n's Add Text Watermark To Image. The API Tester's text-watermark page is the fastest way to see what a given font and opacity setting actually produces.

Why phones hand you sideways photos in the first place

Camera sensors don't physically rotate when you turn the phone. Instead, the device writes an EXIF orientation tag, a number that tells a viewer how to rotate the image before displaying it. Software that reads that tag shows the photo upright. Software that doesn't shows exactly what the sensor captured, and that file stays wrong the moment it leaves an EXIF-aware viewer for a report, an email, or a print vendor's system.

Rotate Image by EXIF Data reads that tag and actually rotates the pixels to match it, so the file is correct everywhere afterward. It only takes two fields.

import requests
import base64

api_key = "YOUR_API_KEY"
base_url = "https://api.pdf4me.com"
endpoint = "/api/v2/RotateImageByExifData"

with open("driver-photo.jpg", "rb") as f:
    doc_content = base64.b64encode(f.read()).decode("utf-8")

payload = {
    "docName": "driver-photo.jpg",
    "docContent": doc_content
}

headers = {
    "Content-Type": "application/json",
    "Authorization": api_key
}

response = requests.post(base_url + endpoint, json=payload, headers=headers)

if response.status_code == 200:
    with open("driver-photo-upright.jpg", "wb") as f:
        f.write(response.content)
Enter fullscreen mode Exit fullscreen mode

That's a genuinely different job from PDF4me's plain Rotate Image endpoint, which turns an image by a fixed angle you specify yourself. Fixed-angle rotation works when you already know the exact correction a whole batch needs. EXIF-based rotation is for when you don't, and can't, because every incoming photo might carry a different tag depending on how it was captured.

No-code equivalents: Make's Auto-Rotate Images by EXIF Data, n8n's Rotate Image By EXIF Data node. The API Tester confirms what a specific file's tag will actually do before it's wired into anything.

Where the no-code coverage runs out

Worth saying plainly: Power Automate has no published action for image watermarking or EXIF-based rotation as of this writing, so a Power Automate-only pipeline needs to call the REST API directly for these three operations. Zapier's rotate action (Rotate Image) only covers the fixed-angle version, not the EXIF-aware one; n8n offers both separately too. If auto-rotation by orientation tag is the actual requirement and Zapier is the only automation layer available, that step currently needs to live somewhere else in the pipeline. Neither gap is a reason to avoid the API, it's a reason to check platform by platform before assuming a specific no-code action already exists.

What's next once the file is correct

Two related endpoints sit one step away from everything above. Once an orientation tag has done its job, some pipelines strip EXIF data out entirely before a file goes anywhere external, since it can carry GPS coordinates and camera details nobody meant to publish: Remove EXIF Tags from Image does that. And if you need to see what's actually in a file's metadata before deciding what to do with it, Get Image Metadata reads it back as structured data instead of guesswork.

Website: pdf4me.com
Documentation: docs.pdf4me.com
Developer portal: dev.pdf4me.com

Top comments (0)