# How to Replace the AtomCam Watermark Logo with Custom PNG Images

> Replace AtomCam watermark with custom PNG images by converting to BGRA raw format and placing it at /media/mmc/watermark.bgra. Customize your device easily.

- Repository: [Mitsuru Nakada/atomcam_tools](https://github.com/mnakada/atomcam_tools)
- Tags: how-to-guide
- Published: 2026-03-07

---

**You can replace the AtomCam watermark by converting a PNG to a BGRA raw format file named `watermark.bgra` and placing it at `/media/mmc/watermark.bgra` on the device.**

The AtomCam firmware overlays a watermark logo on video streams by reading a raw bitmap file from the media partition. According to the mnakada/atomcam_tools source code, you can replace the watermark logo with custom PNG images by converting them to the expected BGRA binary format and deploying the file to the correct path.

## Understanding the Watermark Loading Mechanism

The implementation that loads and paints the logo lives in [[`libcallback/watermark.c`](https://github.com/mnakada/atomcam_tools/blob/main/libcallback/watermark.c)](https://github.com/mnakada/atomcam_tools/blob/main/libcallback/watermark.c). At boot or when triggered by a reload command, the firmware opens `/media/mmc/watermark.bgra` and processes it in three stages.

First, lines 52‑63 read a 2‑integer header representing the image dimensions (`x`, `y`). These are 32‑bit little‑endian integers indicating width and height.

Next, lines 64‑69 read `x * y` pixels (each pixel is 32‑bit BGRA) into `WatermarkBuffer`. If the dimensions exceed the firmware limits, the loader rejects the file with a `watermark file format error`.

Finally, lines 70‑75 pass the bitmap to the video OSD subsystem via `local_sdk_video_osd_set_logo_bitmap` and `sdkosd_update_logo_data`. Lines 89‑108 apply the stored bitmap to both the full‑resolution and the scaled‑down OSD layers, positioning it according to the constants defined in the header.

## Image Requirements and Limitations

Before converting your artwork, ensure it complies with the firmware constraints defined in [`libcallback/watermark.c`](https://github.com/mnakada/atomcam_tools/blob/main/libcallback/watermark.c).

- **Maximum dimensions**: `WATERMARK_MAX_WIDTH = 500` pixels and `WATERMARK_MAX_HEIGHT = 200` pixels (lines 10‑13). Images larger than these limits will be rejected.
- **Color format**: 32‑bit BGRA (Blue, Green, Red, Alpha) with 8 bits per channel.
- **File structure**: A binary header containing two little‑endian 32‑bit integers (width, height) followed immediately by the raw pixel data.
- **Default position**: The logo appears at `WATERMARK_LEFT = 51` pixels from the left and `WATERMARK_BOTTOM = 21` pixels from the bottom (lines 15‑16).

## Converting PNG to BGRA Format

To create a valid `watermark.bgra` file from a standard PNG, use ImageMagick to handle resizing, format conversion, and binary header generation.

```bash

# Resize to stay within the limits (optional)

convert logo.png -resize 500x200\> resized.png

# Export width and height as little‑endian 32‑bit integers

WIDTH=$(identify -format "%w" resized.png)
HEIGHT=$(identify -format "%h" resized.png)

# Create the header (two 32‑bit little‑endian ints)

printf "%d\\0\\0\\0%d\\0\\0\\0" $WIDTH $HEIGHT > watermark.bgra

# Append raw BGRA pixel data (ImageMagick outputs BGRA with -depth 8)

convert resized.png -depth 8 BGRA:- >> watermark.bgra

```

For automated builds, you can use a complete conversion script that enforces size limits and generates the proper binary header:

```bash
#!/usr/bin/env bash

# replace_watermark.sh – generate watermark.bgra from a PNG

set -e

SRC="${1:-logo.png}"
OUT="${2:-watermark.bgra}"

# Enforce size limits

MAX_W=500
MAX_H=200
convert "$SRC" -resize "${MAX_W}x${MAX_H}>" tmp.png

WIDTH=$(identify -format "%w" tmp.png)
HEIGHT=$(identify -format "%h" tmp.png)

# Header: little‑endian 32‑bit width, height

printf "$(printf '\\x%02x\\x%02x\\x%02x\\x%02x' $((WIDTH & 0xFF)) $(((WIDTH>>8) & 0xFF)) $(((WIDTH>>16) & 0xFF)) $(((WIDTH>>24) & 0xFF)))" \
       "$(printf '\\x%02x\\x%02x\\x%02x\\x%02x' $((HEIGHT & 0xFF)) $(((HEIGHT>>8) & 0xFF)) $(((HEIGHT>>16) & 0xFF)) $(((HEIGHT>>24) & 0xFF)))" \
       > "$OUT"

# Append raw BGRA data

convert tmp.png -depth 8 BGRA:- >> "$OUT"

rm -f tmp.png
echo "Created $OUT ( $WIDTH × $HEIGHT )"

```

## Deploying the Custom Watermark

You can deploy the new watermark either during the firmware build process or on a running device.

**During image build**: Replace the pre‑installed file in the overlay directory. The build pipeline copies `overlay_rootfs/etc/watermark.bgra` into the root filesystem when assembling the firmware image.

```bash
cp watermark.bgra overlay_rootfs/etc/watermark.bgra

```

**On a running device**: Copy the file to the MMC partition and trigger a reload.

```bash

# Copy the generated file to the MMC partition

sudo cp watermark.bgra /media/mmc/watermark.bgra

# Trigger immediate reload via the console command

echo "Watermark update" | nc -U /tmp/atomcam_cmd_sock

```

If you do not send the `Watermark update` command, the firmware will load the new logo automatically on the next reboot.

## Verification and Troubleshooting

After deployment, verify the logo appears in the lower‑left corner of the video preview. If the watermark does not appear:

- Check the system logs for `watermark file format error`, which indicates the image exceeds `WATERMARK_MAX_WIDTH` or `WATERMARK_MAX_HEIGHT`.
- Confirm the file is at `/media/mmc/watermark.bgra` and not in a subdirectory.
- Ensure the binary header uses little‑endian byte order; big‑endian systems will misinterpret the dimensions.

## Summary

- The AtomCam firmware loads watermark graphics from `/media/mmc/watermark.bgra` as implemented in [`libcallback/watermark.c`](https://github.com/mnakada/atomcam_tools/blob/main/libcallback/watermark.c).
- Custom images must be converted to BGRA format with a binary header containing two 32‑bit little‑endian integers (width, height).
- Maximum dimensions are strictly enforced at 500×200 pixels.
- Deploy by copying to the MMC partition at runtime or to `overlay_rootfs/etc/watermark.bgra` during builds.
- Use the `Watermark update` command or a reboot to apply changes immediately.

## Frequently Asked Questions

### What is the maximum size for a custom watermark?

The firmware enforces hard limits of **500 pixels wide** and **200 pixels tall** as defined by `WATERMARK_MAX_WIDTH` and `WATERMARK_MAX_HEIGHT` in [`libcallback/watermark.c`](https://github.com/mnakada/atomcam_tools/blob/main/libcallback/watermark.c). Images exceeding these dimensions trigger a `watermark file format error` and are rejected by the loader at lines 52‑63.

### What format does the watermark.bgra file use?

The file uses a custom binary format consisting of an 8‑byte header followed by raw pixel data. The header contains two 32‑bit little‑endian integers representing width and height. The pixel data is 32‑bit BGRA (8 bits per channel), totaling `width × height × 4` bytes.

### How do I force the camera to reload the watermark without rebooting?

Send the `Watermark update` command through the AtomCam control socket. You can invoke this via SSH or a local shell using `echo "Watermark update" | nc -U /tmp/atomcam_cmd_sock`. This triggers the reload routine in [`watermark.c`](https://github.com/mnakada/atomcam_tools/blob/main/watermark.c) without requiring a full system restart.

### Where is the default watermark stored in the firmware source?

The default watermark shipped with the firmware image is located at `overlay_rootfs/etc/watermark.bgra`. When the build system assembles the firmware image, it copies this file into the root filesystem. Replacing this source file bakes your custom logo into every firmware image you generate.