How to Replace the AtomCam Watermark Logo with Custom PNG Images
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). 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.
- Maximum dimensions:
WATERMARK_MAX_WIDTH = 500pixels andWATERMARK_MAX_HEIGHT = 200pixels (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 = 51pixels from the left andWATERMARK_BOTTOM = 21pixels 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.
# 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:
#!/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.
cp watermark.bgra overlay_rootfs/etc/watermark.bgra
On a running device: Copy the file to the MMC partition and trigger a reload.
# 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 exceedsWATERMARK_MAX_WIDTHorWATERMARK_MAX_HEIGHT. - Confirm the file is at
/media/mmc/watermark.bgraand 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.bgraas implemented inlibcallback/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.bgraduring builds. - Use the
Watermark updatecommand 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. 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 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.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →