Skip to main content

Python implementation of a Gemini watermark removal tool using mathematical reverse alpha blending

Project description

Gemini Watermark Remover - Python Edition

PyPI version Python 3.8+ License: MIT

A Python implementation of Gemini watermark removal tool using mathematical reverse alpha blending.

This project is a Python port of GeminiWatermarkTool.

中文文档

Demo

Original (Watermarked) Cleaned

Features

  • 🚀 Easy to use: Pure Python implementation, no compilation needed
  • 🎯 Precise algorithm: Uses reverse alpha blending mathematics
  • 📦 Minimal dependencies: Only requires OpenCV and NumPy
  • 🔄 Batch processing: Supports single file and directory processing
  • 🎨 Auto detection: Automatically detects watermark size (48x48 or 96x96)
  • 🌐 Remote URL support: Process images directly from URLs without downloading

Installation

Using pip (Recommended)

pip install py-gemini-watermark-remover

From Source

Using uv (fast Python package manager):

# Install uv (if not already installed)
curl -LsSf https://astral.sh/uv/install.sh | sh

# Install dependencies (creates virtual environment automatically)
uv sync

# Run directly
uv run python -m gemini_watermark_remover.cli image.jpg

Quick Start

Example Test

# Process example images
uv run python -m gemini_watermark_remover.cli -i examples/example1.jpg -o examples/example1_cleaned.jpg
uv run python -m gemini_watermark_remover.cli -i examples/example2.jpg -o examples/example2_cleaned.jpg

CLI Usage

After installation via pip:

# Simple mode - in-place edit (overwrites original!)
gemini-watermark watermarked.jpg

# Specify output file
gemini-watermark -i watermarked.jpg -o clean.jpg

# Batch process directory
gemini-watermark -i ./input_folder/ -o ./output_folder/

# Force watermark size
gemini-watermark -i image.jpg -o clean.jpg --force-small

# Show banner
gemini-watermark -i image.jpg -o clean.jpg --banner

# Process remote URL directly
gemini-watermark -i "https://example.com/image.webp" -o clean.webp

Or using the module directly:

# Simple mode - in-place edit (overwrites original!)
uv run python -m gemini_watermark_remover.cli watermarked.jpg

# Specify output file
uv run python -m gemini_watermark_remover.cli -i watermarked.jpg -o clean.jpg

# Batch process directory
uv run python -m gemini_watermark_remover.cli -i ./input_folder/ -o ./output_folder/

# Force watermark size
uv run python -m gemini_watermark_remover.cli -i image.jpg -o clean.jpg --force-small

# Show banner
uv run python -m gemini_watermark_remover.cli -i image.jpg -o clean.jpg --banner

# Process remote URL directly
uv run python -m gemini_watermark_remover.cli -i "https://example.com/image.webp" -o clean.webp

Or from source with Python:

# After activating virtual environment
python -m gemini_watermark_remover.cli watermarked.jpg
python -m gemini_watermark_remover.cli -i watermarked.jpg -o clean.jpg

Python API

from gemini_watermark_remover import WatermarkRemover, process_image, process_directory
import cv2

# Method 1: Use convenience function for single file
process_image('watermarked.jpg', 'clean.jpg')

# Method 1b: Process remote URL directly
process_image('https://example.com/image.webp', 'clean.webp')

# Method 2: Use convenience function for directory
success, failed = process_directory('./input/', './output/')

# Method 3: Use WatermarkRemover class (more control)
remover = WatermarkRemover(logo_value=235.0)

# Read image
image = cv2.imread('watermarked.jpg')

# Remove watermark
cleaned = remover.remove_watermark(image)

# Save result
cv2.imwrite('clean.jpg', cleaned)

# Can also add watermark (for testing)
watermarked = remover.add_watermark(image)

Advanced Usage

from gemini_watermark_remover import WatermarkRemover, WatermarkSize
import cv2

# Create custom watermark remover
remover = WatermarkRemover(logo_value=235.0)

# Read image
image = cv2.imread('image.jpg')

# Force small watermark size
cleaned = remover.remove_watermark(
    image,
    force_size=WatermarkSize.SMALL
)

# Use custom alpha map
import numpy as np
custom_alpha = np.ones((48, 48), dtype=np.float32) * 0.5
cleaned = remover.remove_watermark(
    image,
    force_size=WatermarkSize.SMALL,
    alpha_map=custom_alpha
)

# Save
cv2.imwrite('output.jpg', cleaned, [cv2.IMWRITE_JPEG_QUALITY, 100])

CLI Arguments

Argument Description
<file> Simple mode: edit image in-place
-i, --input Input file, directory, or URL
-o, --output Output file or directory
-r, --remove Remove watermark (default behavior)
--add Add watermark (for testing)
--force-small Force 48×48 watermark
--force-large Force 96×96 watermark
--logo-value Logo brightness value (default: 235.0)
-v, --verbose Enable verbose output
-q, --quiet Quiet mode
-b, --banner Show ASCII banner
-V, --version Show version
-h, --help Show help

How It Works

Gemini Watermark Mechanism

Gemini adds watermarks using alpha blending:

watermarked = α × logo + (1 - α) × original

Reverse Alpha Blending Algorithm

Recover original pixels through mathematical inversion:

original = (watermarked - α × logo) / (1 - α)

Automatic Size Detection

Image Size Watermark Size Margin
W ≤ 1024 or H ≤ 1024 48×48 32px
W > 1024 and H > 1024 96×96 64px

API Reference

WatermarkRemover Class

class WatermarkRemover:
    def __init__(self, logo_value: float = 235.0)

    def remove_watermark(
        self,
        image: np.ndarray,
        force_size: Optional[WatermarkSize] = None,
        alpha_map: Optional[np.ndarray] = None
    ) -> np.ndarray

    def add_watermark(
        self,
        image: np.ndarray,
        force_size: Optional[WatermarkSize] = None,
        alpha_map: Optional[np.ndarray] = None
    ) -> np.ndarray

    @staticmethod
    def get_watermark_size(width: int, height: int) -> WatermarkSize

    @staticmethod
    def calculate_alpha_map(bg_capture: np.ndarray) -> np.ndarray

Convenience Functions

def process_image(
    input_path: Union[str, Path],  # Local path or URL
    output_path: Union[str, Path],
    remove: bool = True,
    force_size: Optional[WatermarkSize] = None,
    logo_value: float = 235.0
) -> bool

def is_url(path: str) -> bool  # Check if path is a URL

def load_image_from_url(url: str) -> Optional[np.ndarray]  # Load image from URL

def process_directory(
    input_dir: Union[str, Path],
    output_dir: Union[str, Path],
    remove: bool = True,
    force_size: Optional[WatermarkSize] = None,
    logo_value: float = 235.0
) -> Tuple[int, int]

Supported Image Formats

  • JPEG (.jpg, .jpeg)
  • PNG (.png)
  • WebP (.webp)
  • BMP (.bmp)

Project Structure

py-gemini-watermark-remover/
├── assets/
│   ├── bg_48.png
│   └── bg_96.png
├── src/
│   └── gemini_watermark_remover/
│       ├── __init__.py
│       ├── cli.py
│       └── watermark_remover.py
├── tests/
│   └── test.py
├── examples/
│   ├── example1.jpg
│   ├── example1_cleaned.jpg
│   ├── example2.jpg
│   └── example2_cleaned.jpg
├── README.md
├── README_zh.md
└── pyproject.toml

Performance

  • Single image processing: ~200-800ms (depends on image size and hardware)
  • Batch processing: Sequential processing of multiple files
  • Memory usage: ~3-4x image size (for floating-point operations)

Limitations

  • Only removes visible watermarks (bottom-right semi-transparent logo)
  • Does not remove hidden/steganographic watermarks
  • Designed for Gemini's current watermark pattern (2025)

Troubleshooting

Issue: Processed image looks unchanged

The watermark is semi-transparent. If the background color is similar to the watermark, the difference may be subtle. Zoom to 100% and check the bottom-right corner.

Issue: Wrong watermark size detected

Use --force-small or --force-large to manually specify:

uv run python -m gemini_watermark_remover.cli -i image.jpg -o clean.jpg --force-small

Issue: ModuleNotFoundError

Make sure dependencies are installed:

uv sync

Comparison with C++ Version

Feature C++ Version Python Version
Installation No installation (single file) Requires Python environment
File size ~15MB ~2KB (excluding dependencies)
Speed Fast Medium (NumPy optimized)
Code size ~1000 lines ~600 lines
Development Requires compilation Edit and run
Easy to modify Medium Easy
Best for Distribution to users Development/Integration

License

MIT License

Disclaimer

This tool is for personal and educational use only. Users must ensure their use complies with applicable laws and terms of service.

The author is not responsible for any data loss or image corruption caused by using this tool. Please backup original images before use.

Credits

Python implementation based on GeminiWatermarkTool C++ version.


If this tool helped you, please give the project a ⭐

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

py_gemini_watermark_remover-0.2.7.tar.gz (1.9 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

py_gemini_watermark_remover-0.2.7-py3-none-any.whl (24.8 kB view details)

Uploaded Python 3

File details

Details for the file py_gemini_watermark_remover-0.2.7.tar.gz.

File metadata

File hashes

Hashes for py_gemini_watermark_remover-0.2.7.tar.gz
Algorithm Hash digest
SHA256 64c789904edfbe3b6a14f14e9f44021f6411cf9bb96ab8aa580556213457d7b9
MD5 0ce56cfcd18c88b6df3b9df8ad18b849
BLAKE2b-256 2a44c56a67692fca431c280f7e9a3528f50ede1e928c3b315e83c46772ce0bc7

See more details on using hashes here.

File details

Details for the file py_gemini_watermark_remover-0.2.7-py3-none-any.whl.

File metadata

File hashes

Hashes for py_gemini_watermark_remover-0.2.7-py3-none-any.whl
Algorithm Hash digest
SHA256 ed75806d8dac699a8792ffb94ee252f96298e0a8d3924564e13cdb16401309c3
MD5 44ba72053274525fe52e1273d3994ef0
BLAKE2b-256 4087542f2d223913e058c650e000574f35c9fa0a10d62c7e58f2b7969accca6d

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page