Diagnosed visible faint grey rectangle around B&W ink art images on pages with pure-white backgrounds. Root cause was format encoder luminance shift in near-white pixels: Source JPG corner: (253,253,253) = #FDFDFD = 99.2% white AVIF q=65 (default): (250,250,250) = #FAFAFA = 98.0% (1.2% halo) WebP q=80 (default): (249,249,249) = #F9F9F9 = 97.6% (1.6% halo) Two changes: 1. avifenc now uses -y 444 (full chroma subsampling) instead of default 4:2:0. Brings AVIF corner to #FBFBFB = 98.4%, smaller file size as a bonus (~10% reduction on a typical art image). 2. WebP default quality raised 80 → 90. Reaches #FDFDFD = exact match with source JPG. File size increases ~30% but eliminates the halo entirely for WebP-capable browsers (vast majority). AVIF still has 0.4% residual halo (libavif 0.11.1 ceiling at this quality range — pushing higher yields no improvement, only file size). Acceptable tradeoff: WebP is the served-by-default fallback when AVIF isn't perfect. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
h4b-image-optim
ICC-safe image optimisation with WebP + AVIF generation for WordPress. Replaces Smush Pro without the grey-wash bug. No CDN.
Status: v0.1.0 MVP — under active development. Tested on AlmaLinux 9 + PHP 8.4 + Imagick 3.8.1.
Why this exists
Smush Pro's Ultra mode (lossy=2 + strip_exif=true) destroyed 1,345 high-contrast B&W ink art JPGs on rds.ink by stripping ICC profiles and applying aggressive JPEG quantisation. The diagnosis, rescue, and a full design document are in the sibling image-rescue/ directory.
This plugin is the structural fix: an in-house Smush replacement that never strips ICC profiles, with full source-code ownership and zero CDN dependency.
Features (v0.1)
- ✅ JPEG / PNG optimisation in place (Imagick + jpegoptim/pngquant)
- ✅ ICC profile preservation (the Smush-bug fix)
- ✅ EXIF orientation applied + GPS stripped for privacy
- ✅ WebP sibling generation (cwebp)
- ✅ AVIF sibling generation (avifenc, queued via WP-Cron)
- ✅ Backup of originals to
wp-content/h4b-img-originals/, pruned after 90 days - ✅ WP-CLI:
wp h4b-img status,wp h4b-img optimise --id=<n> - 🔜 Bulk processing (
wp h4b-img bulk) - 🔜 Picture-tag rewriting + .htaccess fallback
- 🔜 Admin settings page
- 🔜 Migration command from Smush metadata
Required system tools
Install on AlmaLinux 9:
dnf install --setopt=install_weak_deps=False \
libwebp-tools jpegoptim libjpeg-turbo-utils libavif-tools pngquant
Verify with:
wp h4b-img status
Settings (v0.1 — set via WP-CLI)
wp option get h4b_image_optim_settings
wp option patch update h4b_image_optim_settings jpeg_quality 90
Key defaults:
| Setting | Default | Why |
|---|---|---|
jpeg_quality |
85 | Industry standard; visually lossless for art |
jpeg_chroma_subsampling |
4:4:4 |
The Smush-bug fix — no chroma loss on edges |
preserve_icc_profile |
true |
Critical — never strip ICC |
generate_webp |
true |
Always make .webp sibling |
generate_avif |
true |
Always make .avif sibling (background) |
avif_async |
true |
Don't block upload UI |
backup_originals |
true |
Always |
backup_prune_days |
90 |
Cron prunes after 90 days |
resize_max_width |
2560 |
Hard cap on uploaded image size |
Uninstall
uninstall.php deletes the settings option and clears cron hooks. It does not delete backup files or .webp/.avif siblings — those are user data.
License
GPL-2.0-or-later.