Bulk Watermark Manager
Batch watermark images in your WordPress Media Library with a modern, intuitive interface. Select images, configure your watermark, preview the result, and apply — all without leaving WordPress admin.
by Trang Dev · github.com/trangc0de200/bulk-watermark-manager · website
Install
No release zip yet. The repository archive installs, but the folder name will carry the branch suffix and updates will not flow:
wp plugin install https://github.com/trangc0de200/bulk-watermark-manager/archive/refs/heads/main.zipReadme
Bulk Watermark Manager
Batch watermark images in your WordPress Media Library with a modern, intuitive interface. Select images, configure your watermark, preview the result, and apply — all without leaving WordPress admin.
Screenshots
| Main Interface | Watermark Configuration | Live Preview |
|---|---|---|
Screenshots coming soon — the plugin is actively maintained.
Table of Contents
- Features
- Quick Start
- Requirements
- Installation
- Usage
- Technical Reference
- Hooks & Metadata
- Security
- Contributing
- Changelog
- License
Features
| Feature | Description |
|---|---|
| Bulk Processing | Apply watermarks to hundreds of images simultaneously |
| Live Preview | Canvas-based real-time preview updates as you adjust settings |
| 9 Position Anchors | Place watermarks at any corner, edge, or center |
| Fine-Tuned Controls | Adjustable size (5–80%), opacity (10–100%), and edge padding (0–60px) |
| Original Backups | Automatically save _orig copies before modifying images |
| Smart Filtering | Filter by upload date or watermark status |
| Search | Find images by title or filename with debounced search |
| Progress Tracking | Real-time progress bar and per-image success/error log |
| Watermark Badges | Visual indicator on already-watermarked images |
| WP Media Picker | Select watermark images using the native WordPress picker |
Quick Start
1. Install & activate the plugin
2. Go to Media → Watermark Manager
3. Select images from the grid
4. Choose a watermark image
5. Adjust position, size, opacity, and padding
6. Preview on canvas, then click Apply
Requirements
| Dependency | Minimum Version | Notes |
|---|---|---|
| WordPress | 5.0 | Tested up to the latest stable release |
| PHP | 7.4 | GD extension must be enabled |
| PHP GD extension | — | Used for all server-side image operations |
| User role | Editor+ | Requires upload_files capability |
Verify GD is installed
php -m | grep -i gd
Expected output contains gd.
If GD is missing, install it:
# Debian / Ubuntu
sudo apt install php-gd && sudo systemctl restart php-fpm
# CentOS / AlmaLinux / RHEL
sudo dnf install php-gd && sudo systemctl restart php-fpm
# macOS (Homebrew)
brew install php && brew services restart php
Installation
Option 1 — WordPress Admin Upload
- Download the repository as a ZIP file.
- Navigate to Plugins → Add New → Upload Plugin.
- Upload the ZIP and click Install Now.
- Activate the plugin.
- Go to Media → Watermark Manager.
Option 2 — FTP / File Manager
- Upload the
bulk-watermark-managerfolder to/wp-content/plugins/. - Activate via Plugins in your WordPress admin.
- Go to Media → Watermark Manager.
Option 3 — WP-CLI
wp plugin install --activate /absolute/path/to/bulk-watermark-manager
Usage
Selecting Images
- Individual selection — Click any image in the grid to toggle its selection. A green border and checkmark indicate selected items.
- Bulk selection — Use Select All / Deselect in the toolbar.
- The header counter updates in real time as you select or deselect.
Filtering & Searching
| Control | Purpose |
|---|---|
| Search box | Filter by image title or filename (debounced, 350ms) |
| Date filter | Show images uploaded in a specific month |
| Status filter | Show only watermarked or non-watermarked images |
Configuring Watermarks
Click Set Watermark (N) to open the configuration panel:
| Setting | Range | Default | Effect |
|---|---|---|---|
| Watermark Image | Any image from Media Library | — | Source of the watermark overlay |
| Position | 9 anchors (3×3 grid) | Bottom-right | Where on the image the watermark is placed |
| Size | 5–80% | 25% | Watermark width as a percentage of base image |
| Opacity | 10–100% | 80% | Transparency level of the watermark |
| Edge Padding | 0–60px | 10px | Distance from the nearest image edge |
| Save Original | On/Off | On | Stores a _orig copy before overwriting |
Previewing
The right-hand panel renders a live canvas preview using the first selected image. All slider changes reflect instantly — no save required to preview.
Applying
Click Apply to N images. The progress overlay shows:
- An animated progress bar
- A running count (
N / M) - A scrollable log with per-image success (
OK) or failure (FAIL) entries
After completion, the grid updates in place and the watermark badge appears on processed images.
Technical Reference
Image Loading Flow
Page Load / Filter Change
│
▼
$.post( 'wp_ajax_bwm_load_images' )
│
▼
WP_Query( post_type=attachment, mime_type=image, ... )
│
▼
Post meta _bwm_watermarked merged into results
│
▼
Paginated JSON response (32 items/page)
│
▼
Grid renders with selection state
Watermark Processing Flow
User clicks "Apply to N images"
│
▼
Sequential $.post() per attachment_id
│
├──► PHP GD: imagecreatefromjpeg / png / webp
├──► PHP GD: resize watermark proportionally
├──► PHP GD: alpha manipulation for opacity
├──► PHP GD: imagecopy onto base at position
├──► PHP GD: imagejpeg / imagepng / imagewebp
├──► update_post_meta( _bwm_watermarked )
├──► wp_update_attachment_metadata()
└──► JSON response { url: "...?v=timestamp" }
Supported Image Formats
| Role | JPEG | PNG | WebP |
|---|---|---|---|
| Base image | ✅ | ✅ | ✅ |
| Watermark image | ✅ | ✅ | ✅ |
Hooks & Metadata
Post Meta
| Key | Type | Description |
|---|---|---|
_bwm_watermarked |
int (0 or 1) |
Whether the attachment has been watermarked |
_bwm_wm_id |
int |
WordPress attachment ID of the watermark image used |
AJAX Actions
| Action | Callback | Auth |
|---|---|---|
bwm_load_images |
wp_ajax_bwm_load_images |
Nonce only |
bwm_apply_watermark |
wp_ajax_bwm_apply_watermark |
Nonce + upload_files capability |
Nonce
All AJAX requests include BWM.nonce, verified server-side with wp_verify_nonce(). The nonce is initialized via wp_create_nonce('bwm_nonce') and passed to JavaScript through wp_localize_script().
Security
ABSPATHguard prevents direct file access.- All AJAX endpoints verify the WordPress nonce before processing.
current_user_can('upload_files')gates watermark application.- Input sanitization:
sanitize_text_field(),intval(),floatval()on all user-supplied values. - MIME type and file existence validated server-side before GD operations.
Contributing
Contributions are welcome. Please follow these guidelines:
- Fork the repository and create a feature branch (
feature/your-feature-name). - Write clean, readable code — follow the existing style.
- Test thoroughly on a local WordPress installation before submitting.
- Commit with clear messages — use conventional commit format.
- Open a Pull Request against
mainwith a description of your changes.
For bug reports and feature requests, open an issue on GitHub.
Changelog
All notable changes are documented below. This project follows Keep a Changelog conventions.
1.0.0 — 2024
Added
- Bulk watermark application to Media Library images with sequential AJAX processing.
- Live canvas preview with real-time slider updates.
- 9-position placement grid (top/middle/bottom × left/center/right).
- Size, opacity, and edge padding controls.
- Automatic original image backup with
_origsuffix. - Image search, date filter, and watermark-status filter.
- Watermark status badge on processed images.
- Progress bar with per-image success/error log.
- Native WordPress Media Library picker for watermark selection.
- Support for JPEG, PNG, and WebP base and watermark images.
- Responsive admin UI with loading skeleton and smooth transitions.
License
GPL-2.0 © Trang Dev
Built with care for the WordPress community
Read the full README on GitHub →
Releases
| Tag | Published |
|---|---|
| 1.0.0 | Jun 3, 2026 |
These releases are tags only. The author does not attach a packaged zip, so there are no download counts to report.