Title: Australcode Uniform Images
Author: australcode
Published: <strong>June 3, 2026</strong>
Last modified: June 8, 2026

---

Search plugins

![](https://ps.w.org/australcode-uniform-images/assets/banner-772x250.png?rev=3564096)

![](https://ps.w.org/australcode-uniform-images/assets/icon-256x256.png?rev=3559924)

# Australcode Uniform Images

 By [australcode](https://profiles.wordpress.org/australcode/)

[Download](https://downloads.wordpress.org/plugin/australcode-uniform-images.0.37.0.zip)

 * [Details](https://wordpress.org/plugins/australcode-uniform-images/#description)
 * [Reviews](https://wordpress.org/plugins/australcode-uniform-images/#reviews)
 *  [Installation](https://wordpress.org/plugins/australcode-uniform-images/#installation)
 * [Development](https://wordpress.org/plugins/australcode-uniform-images/#developers)

 [Support](https://wordpress.org/support/plugin/australcode-uniform-images/)

## Description

**Australcode Uniform Images** solves the classic WooCommerce catalog problem: product
photos with different proportions that the theme crops brutally to align the grid.
This plugin makes them uniform without cropping — it adds smart padding over a colored
canvas (white by default), optionally trims the uniform background first to normalize
inconsistent margins, and delivers each thumbnail in AVIF + WebP + JPEG using the`
<picture>` element.

#### Key differentiators

 * **No accidental crops** — the entire product fits inside the thumbnail, always.
   Compare with “smart crop” plugins that guess the subject and sometimes fail on
   small or asymmetric products.
 * **Real `<picture>` markup** — multi-source with AVIF + WebP + JPEG fallback. **
   Survives any page cache** (LiteSpeed, WP Rocket, Cloudflare APO, W3 Total Cache)
   because it does not use `Vary: Accept`. The browser picks the optimal format;
   the cache serves HTML without negotiation.
 * **4-tier quality preset** — Maximum / High / Standard / Economy with per-format
   values calibrated (e.g. Standard = AVIF Q60, WebP Q82, JPEG Q85 — visually indistinguishable
   from the original at half the size).
 * **HPOS-ready from day one** — declares `custom_order_tables` and `cart_checkout_blocks`
   compatibility without any setup.
 * **Cloudflare Image Transformations (CIT)** — optional integration to serve via
   Cloudflare edge (`/cdn-cgi/image/format=auto`) with automatic availability detection
   on your zone. If CIT is not enabled on your CF plan, the plugin keeps serving
   local derivatives without breaking anything.

#### Free (no license required)

 * **Bulk regenerate with Action Scheduler** — async processing resumable after 
   worker death, error classification (`oom`, `missing_original`, `engine_failed`,`
   fs_permission`), scope filters (`auto` = products only based on Settings; `all-
   used` = every image referenced in posts/products/Bricks templates/terms).
 * **Embedded sample test** — processes 1-5 images on demand and shows the before/
   after grid with bytes and % savings. Available on the **Settings** page (“Quick
   preview”) and on **Bulk regenerate** (“Generate sample”).
 * **Health page with CDN detection** — engine diagnostics, encoders, filesystem
   permissions, detected competing plugins (Smush/EWWW/ShortPixel/Imagify), Cloudflare
   Polish status (alerts if active — incompatible with the plugin’s AVIF/WebP), 
   Image Prioritizer (Performance Lab) status with automatic detection.
 * **WP-CLI — 9 commands** — 7 free: `wp acimg health`, `stats`, `regenerate`, `
   derivatives <id>`, `purge-cache`, `restore-originals`, `migrate-from-sir`. 2 
   Pro: `wp acimg doctor` (extended diagnostics) and `wp acimg reset` (full state
   reset).

#### Pro (license required)

 * **Cloudflare Image Transformations (CIT) delivery** — emits `<img>` with CIT 
   URLs (`/cdn-cgi/image/format=auto`) instead of local derivatives when CIT is 
   enabled on your zone. Defensive automatic fallback to the normal path if CIT 
   is unavailable.
 * **Media Library audit + cleanup** — orphan image detector that understands **
   Bricks Builder** (PHP serialize), `wp_termmeta`, WooCommerce shortcodes, custom
   meta. Trash mode with typed confirmation, immutable audit log, and an `untrash`
   endpoint for rollback.
 * **Image Health Monitor** — weekly cron that scans for missing derivatives, stale
   derivatives, Cloudflare Polish conflicts, and storage usage. Email digest to 
   the admin only when there are actionable findings.
 * **AI Alt Text BYOK** — alt text generation per attachment via OpenAI Vision (`
   gpt-4o-mini`) or Anthropic Vision (`claude-haiku-4-5`). Bring Your Own Key (no
   Merchant of Record over AI costs). Context enrichment with WooCommerce product
   title + category + brand.
 * **Catalog Watch + Auto-Heal** — daily cron that detects ghost derivatives (DB
   rows without files), orphan files (files without DB rows), products with broken
   thumbnails. Auto-heal with dry-run preview + strict path validation. Persistent
   admin notice when there are actionable issues.
 * **Multi-Site Manager** (Agency tier+) — centralized dashboard to monitor up to
   25 client sites from a single wp-admin. BYO Application Password, aggregated 
   metrics (derivatives + bytes + issues), automatic hourly sync + ad-hoc. No external
   services: direct wp-admin  wp-admin communication via native REST.
 * **CIT Cost Analyzer** — daily pull from Cloudflare GraphQL Analytics API. MTD
   cost + monthly projection + peak day to identify spikes. BYO API token (CF authenticates
   directly).

#### Integration with other plugins

 * **Image Prioritizer / Performance Lab** — Australcode Uniform Images detects `
   fetchpriority="high"` and propagates correct loading/decoding to the final `<
   picture>`. Native LCP optimization.
 * **Bricks Builder** — supports `wp_get_attachment_image` and optional output buffer
   rewriter for themes/page builders that bypass that filter.
 * **WP Rocket / a3 Lazy Load** — compatible with `data-src`/`data-sizes` lazy loaders(
   reads both if present).

#### v1.0 non-goals

 * **Smart crop** — would break the “no cropping” promise. If you need that, this
   plugin is not for you.
 * **SaaS-only / phone home** — the plugin is 100% local. All optimization happens
   on your own server.
 * **JPEG XL** — format still immature in browsers. We will reevaluate in 2027.

#### How it compares

 Concern
 Smush / ShortPixel / Imagify Australcode Uniform Images

 Product photo cropping
 Smart crop (algorithm guesses) None — pads to a uniform
canvas, full product always visible

 Modern formats
 WebP / AVIF (Pro/paid tiers) AVIF + WebP + JPEG via `<picture>`
element

 Page cache
 `Vary: Accept` (breaks LiteSpeed, WP Rocket, Cloudflare APO) `<picture
>` element (cache-safe by design)

 Pricing model
 $5-15/month SaaS subscription One-time license, no SaaS dependency

 WooCommerce-specific
 Generic optimizer Built for product grids — reads `wp_get_registered_image_subsizes()`,
respects WC thumbnail_cropping setting

 Processing location
 SaaS server (your images leave) 100% local on your server

The other plugins optimize **any image**. Australcode Uniform Images does **one 
job extremely well**: uniform product thumbnails for WooCommerce grids, served cache-
safe. If you already have one of the big plugins active, you can run Australcode
side-by-side — it only touches images on registered WooCommerce sizes.

### External services

This plugin connects to third-party services **only when you explicitly enable
 
the corresponding optional feature
. The free, core functionality (uniform
 images,
AVIF/WebP/JPEG `<picture>`, bulk regenerate, health) runs 100% on your own server
and contacts no external service.

#### Lemon Squeezy (license validation — Pro)

When you activate, validate, or deactivate a Pro license, the plugin sends your
**
license key** and your **site domain** to the Lemon Squeezy License API (host `api.
lemonsqueezy.com`, path `/v1/licenses/`). A background cron revalidates the license
roughly every 24 hours. This only happens if you enter a license key. No data is
sent in the free version.

 * Terms of Service: https://www.lemonsqueezy.com/terms
 * Privacy Policy: https://www.lemonsqueezy.com/privacy

#### OpenAI / Anthropic (AI Alt Text — Pro, Bring Your Own Key)

If you enable **AI Alt Text** and provide your own API key, the plugin sends the
**
image** (as a base64 data URI) plus the related **WooCommerce product context** (
title, category, brand) to the provider you choose, to generate alt text:

 * OpenAI Vision (`gpt-4o-mini`) — host `api.openai.com`, path `/v1/chat/completions`
    - Terms: https://openai.com/policies/terms-of-use
    - Privacy: https://openai.com/policies/privacy-policy
 * Anthropic Vision (`claude-haiku-4-5`) — host `api.anthropic.com`, path `/v1/messages`
    - Terms: https://www.anthropic.com/legal/consumer-terms
    - Privacy: https://www.anthropic.com/legal/privacy

This runs only when you trigger alt text generation and only with the key you
 supply.
The plugin is not a Merchant of Record for these AI costs (BYOK).

#### Cloudflare (Image Transformations + Cost Analyzer — Pro)

If you enable **Cloudflare Image Transformations (CIT)**, image URLs of your own

site are served through Cloudflare’s edge (`/cdn-cgi/image/...`) so Cloudflare can
transform them on-demand. If you enable the **CIT Cost Analyzer**, the plugin queries
the Cloudflare GraphQL Analytics API (host `api.cloudflare.com`, path `/client/v4/
graphql`) with the API token **you provide** and your zone identifier, to report
usage and cost. The plugin also performs a HEAD request to one of **your own** derivative
URLs to detect whether CIT and Cloudflare Polish are active on your zone (no third-
party data is sent in that detection).

 * Terms of Service: https://www.cloudflare.com/terms/
 * Privacy Policy: https://www.cloudflare.com/privacypolicy/

## Screenshots

 * [[
 * **Dashboard** — catalog metrics: processed images, generated derivatives, storage
   used, % savings when serving AVIF vs original, active quality preset, current
   bulk run.
 * [[
 * **Settings** — 4-tier quality preset, per-size override, visual canvas color 
   picker, sticky save bar that appears when changes are detected.
 * [[
 * **Bulk regenerate** — scope dropdown with real-time count, dry-run with storage
   and time estimation, embedded sample test with before/after grid.
 * [[
 * **Health** — full diagnostic: active engine + codec capabilities matrix, DB tables
   with row count, applied migrations, CDN edge (Cloudflare Polish/Mirage + Image
   Transformations detection).
 * [[
 * **Clean library** (Pro) — orphan image audit with Bricks Builder + wp_termmeta
   + WooCommerce shortcodes detection. Trash mode with typed confirmation and audit
   log.
 * [[
 * **Catalog Watch** (Pro) — daily cron that detects ghost derivatives, orphan files,
   and products with broken images. Auto-heal with dry-run preview before applying.
 * [[
 * **Multi-Site Manager** (Agency / Network) — centralized dashboard to monitor 
   up to 25 sites (Agency) or 1000 sites (Network) of clients. BYO Application Password,
   aggregated metrics + status badges.
 * [[
 * **License management** (Pro) — activate, validate, and deactivate your license;
   per-tier activation counter; one-click upgrade path to a higher tier.

## Installation

#### Via WordPress Admin (recommended)

 1. Go to **Plugins  Add new** in your WP admin, search for “Australcode Uniform Images”
    and click Install + Activate.
 2. Navigate to the new top-level menu **Australcode Image  Settings** and choose your
    quality preset (default Standard works well for most cases).
 3. Go to **Australcode Image  Bulk regenerate**, run a Sample Test with one product
    to validate visually, then click “Start bulk” to process the full catalog.

#### Via WP-CLI

    ```
    `
    ```

wp plugin install australcode-uniform-images –activate
 wp acimg health # verify
everything is OK wp acimg regenerate # bulk dry-run wp acimg regenerate –start –
yes # starts bulk in the background `

## FAQ

### Is it compatible with WooCommerce HPOS (High-Performance Order Storage)?

Yes. Compatibility with `custom_order_tables` and `cart_checkout_blocks` is declared
from day one via `before_woocommerce_init`. No manual configuration required.

### Does it work with Cloudflare?

Yes, and well. The plugin emits `<picture>` with `<source>` per MIME type — **it
survives Cloudflare APO** and any page cache perfectly because it does NOT use `
Vary: Accept` (which would break caching).

If you have **Cloudflare Pro+**, you can enable **Image Transformations** from Settings
CDN edge. The plugin automatically detects whether CIT is available on your zone
and emits `/cdn-cgi/image/` URLs that CF transforms on-demand with `format=auto`.

**Caution with Cloudflare Polish**: if active, it re-compresses the AVIF/WebP that
the plugin already optimized — double compression equals visual artifacts. The plugin
detects this on the Health page and alerts you with an admin notice. Recommendation:
disable Polish, keep APO.

### Which image engine does it use?

**Imagick** (preferred) with `libheif` for AVIF. **GD** as fallback. **libvips**
is wired in the code but requires bundled binaries (not included in v0.x — future
sprint). The active engine and its capabilities (read/write per format) appear on**
Health  Image engines**.

### Do I need anything special for AVIF?

Imagick compiled with `libheif` (common on modern hosts: Kinsta, WP Engine, SiteGround,
recent Cloudways). If Imagick does not support AVIF, the plugin still emits WebP
+ JPEG and the Health page reports the limitation. **You do not get stuck without
anything** — you just lose the most efficient format.

### How much storage does it use?

Estimate: ~700 KB of derivatives on average per original image at Standard preset(
varies a lot by content type — product photos with a uniform background compress
better). For a catalog of 1,000 products with one image each, that’s ~700 MB of 
derivatives. The plugin **NEVER touches the original** on disk, so you need space
for original + derivatives.

### How do I regenerate after changing settings?

Change settings on **Australcode Image  Settings**, save (the plugin shows a modal
warning you that existing derivatives are invalidated), and then go to **Bulk regenerate**
or run `wp acimg regenerate --start --yes`. The plugin keeps serving the old derivatives
until regeneration completes — **zero visual downtime**.

### Conflicts with Smush / EWWW / ShortPixel / Imagify?

Yes, **disable those plugins** before installing Australcode Uniform Images. The
Health  Doctor page detects them and alerts you. The typical conflict is that those
plugins also hook into `wp_get_attachment_image` and rewrite the HTML — the output
ends up inconsistent.

### Does it have WP-CLI?

Yes, 9 commands under `wp acimg <subcommand>`. Seven are free: health (CI smoke 
test), stats, regenerate, derivatives , purge-cache, restore-originals, and migrate-
from-sir. Two require a Pro license: doctor (extended diagnostics) and reset (resets
all persisted state without deactivating). Each command supports `--format=json`.`
wp help acimg` lists them all.

### How do I report a bug or request a feature?

Open a support thread in the WordPress.org plugin support forum (linked from the
plugin page sidebar). For Pro license-related issues, contact support@australcode.
io.

## Reviews

There are no reviews for this plugin.

## Contributors & Developers

“Australcode Uniform Images” is open source software. The following people have 
contributed to this plugin.

Contributors

 *   [ australcode ](https://profiles.wordpress.org/australcode/)

[Translate “Australcode Uniform Images” into your language.](https://translate.wordpress.org/projects/wp-plugins/australcode-uniform-images)

### Interested in development?

[Browse the code](https://plugins.trac.wordpress.org/browser/australcode-uniform-images/),
check out the [SVN repository](https://plugins.svn.wordpress.org/australcode-uniform-images/),
or subscribe to the [development log](https://plugins.trac.wordpress.org/log/australcode-uniform-images/)
by [RSS](https://plugins.trac.wordpress.org/log/australcode-uniform-images/?limit=100&mode=stop_on_copy&format=rss).

## Changelog

#### 0.37.0

 * **`wp acimg migrate-from-sir` is now free** — import your Smart Image Resize 
   settings (background color, trim, sizes) into Australcode with one command. Makes
   switching effortless.
 * **New output-format controls (free)** — force JPEG-only or PNG-only output per
   your needs, plus an optional delivery filesystem check on the Health page. Off
   by default; existing sites unaffected.
 * **Catalog Watch repair now runs in the background** — on large catalogs the repair(
   and its preview) no longer time out behind Cloudflare. Progress is shown and 
   you can close the page; the job continues. (Pro)
 * **Cleanup, Multi-Site and CIT Cost pages redesigned** — Cleanup is now a 3-step
   wizard (Audit  Review  Move), Multi-Site has a guided empty state, and CIT Cost
   leads with a budget KPI + projection.
 * **Fixed** — Settings page polish: the AI Alt Text and aspect-ratio override sections
   now align with the settings column, and their “Pro” badges correctly disappear
   once a Pro license is active.

#### 0.36.1

 * Page-builder coverage extended to Beaver Builder (`_fl_builder_data`) and Oxygen(`
   ct_builder_shortcodes`). The detection now combines two strategies per builder:
   structured ID extraction (precise for Bricks/Elementor) and a universal URL scan
   of the builder’s stored markup (covers Beaver, Oxygen, and any builder that embeds
   the image URL). Divi/WPBakery remain covered via `post_content`.

#### 0.36.0

 * Page-builder coverage: Bulk Regenerate (“All used images” scope) now detects 
   images placed directly in Bricks and Elementor templates — they live in the builder’s
   own storage (`_bricks_page_content`, `_elementor_data`), outside `post_content`,
   so previous versions never found or optimized them. Divi was already covered (
   it stores in `post_content`). The frontend delivery already handled any `<img
   >` from any builder; this closes the generation side.
 * Bulk runs now process exactly what the chosen scope selected: the “All used images”
   scope optimizes every used image (products and non-products alike), instead of
   silently skipping images whose post type isn’t in the processing filter. The 
   per-type filter still governs automatic processing on upload.

#### 0.35.0

 * New (opt-in): auto-detect transparency. When enabled, images whose original has
   significant transparency (logos, cut-out products with shadows) keep their alpha
   channel — the plugin uses a transparent canvas and a PNG raster fallback instead
   of flattening onto the canvas color. WebP and AVIF already preserve transparency.
   Off by default, so existing sites are unaffected until you turn it on (which 
   regenerates derivatives). Set it in Settings  Formats & quality  Transparency.

#### 0.34.1

 * Internationalization: the admin JavaScript layer is now fully translatable. All
   dynamic UI text in Bulk Regenerate and Clean Library (counters, confirmations,
   progress, summaries, error messages) — plus the previously localized Catalog 
   Watch, Multi-Site, CIT Cost Analyzer and settings preview — now routes through
   WordPress translations instead of hardcoded strings.
 * The English (en_US) translation bundle is now 100% complete.
 * No behavior changes: every string keeps its original fallback until the site’s
   active language provides a translation.

#### 0.34.0

 * Pro: new per-aspect-ratio mode overrides. For each main WooCommerce size you 
   can choose how each aspect ratio is processed (square 1:1, 4:3, 16:9, portrait,
   etc.): uniform with canvas, proportional without cropping, or skip. For example,
   keep square images on “proportional” while the rest of the size follows its base
   mode. Available on all paid plans.
 * The per-aspect override is wired into the generation pipeline (upload and bulk
   regeneration) and into derivative invalidation, so changing it regenerates only
   what is needed.
 * Visibility: the Dashboard now shows how many images were skipped by the context
   filter (not attached to a processable post type), with a shortcut to adjust the
   filter. Avoids the “I uploaded an image and nothing happened” confusion.

#### 0.33.2

 * Security: REST endpoints that operate on attachments now verify the edit/delete
   capability per attachment (current_user_can edit_post/delete_post), in addition
   to the general manage_woocommerce gate.

#### 0.33.1

WP.org re-submission compliance + listing polish. No user-facing behavior changes—
safe in-place upgrade.

 * **External services URLs no longer pingable as 404** — the readme’s “External
   services” section referenced API endpoints (`api.lemonsqueezy.com`, `api.openai.
   com`, `api.anthropic.com`, `api.cloudflare.com`) as full URLs. WP.org’s review
   scanner pings every URL in the readme and flagged the Lemon Squeezy endpoint 
   as a broken Terms/Privacy URL. Endpoints are now declared as host + path (not
   full clickable URLs); Terms/Privacy links remain and resolve.
 * **Explicit output-buffer close** — `OutputBufferHook` (opt-in feature, off by
   default) now closes its `ob_start()` buffer explicitly on `shutdown`, guarded
   by `ob_get_level()`. Same rewritten output, paired open/close as WP.org guidelines
   expect. WP 6.5+ compatible.
 * **Banners + branding** — re-generated WP.org banners with the current name (Australcode
   Uniform Images) and version; renamed the last legacy global variable in the bootstrap
   file.
 * **Listing polish** — sharper short description and tags for the target niche,
   added Upgrade Notice, fixed screenshot #8 caption, aligned WP-CLI command count
   between Description and FAQ.

Internal: 296/296 unit tests passing.

#### 0.33.0

Lote C — WP.org compliance fixes residuales para re-submission. Cierra los puntos
del review WP.org del 20-May que no quedaron cubiertos por el rebrand inicial. Cero
breaking changes a nivel de usuario.

 * **`league/container` bumped 4.2.5  5.2.0** — la librería de DI bumpea major sin
   breaking changes en la API que el plugin usa (`add`, `addShared`, `delegate(new
   ReflectionContainer(true))`, `get`). 296/296 unit tests passing post-bump; runtime
   integración validada en wp-sandbox-staging.
 * **Removed GitHub URLs from readme.txt** — la documentación pública del plugin(
   Installation, FAQ “How do I report a bug?”, footer) apunta ahora exclusivamente
   a recursos accesibles públicamente: WP.org plugin page para download/install,
   support forum WP.org para reportes de issues free, support@australcode.io para
   Pro license issues. El repo de desarrollo es privado por diseño; los users no
   necesitan acceso al código fuente para usar el plugin (que viene con el ZIP del
   listing WP.org).
 * **Internal repo rename** — el repo de desarrollo se renombró a `australcode-uniform-
   images` para coherencia con el slug del plugin (era `conecta-image-resize` del
   codename interno legacy). Cambio invisible al usuario final; solo afecta workflow
   del autor.

Internal: 296/296 unit tests passing. Plugin Check sobre v0.33.0 esperado 0 errors/
155 warnings (baseline S3 mantenido desde v0.23.14).

#### 0.32.0

Lote B — fix de 4 hallazgos P1 de UX clarity de la prueba humana en drbrowns prod
sobre v0.31.0. Cero breaking changes — solo correcciones de copy + tooltips. Safe
in-place upgrade.

 * **Dashboard header — botones con contexto** — los CTAs del header del Dashboard
   pasaron de etiquetas neutras (“Generar muestra” / “Configuración”) a etiquetas
   con flecha de navegación + tooltip explicativo: “Probar con muestra ” (con tooltip“
   Probar el plugin con 1–5 imágenes antes de procesar el catálogo completo”) y “
   Configuración ” (con tooltip “Calidad, formatos, tamaños y delivery del plugin”).
   La flecha indica que llevan a otra página; el tooltip da el porqué.
 * **Settings — copy de heurística sizes legible** — el lede “Por cada size, elige
   cómo el plugin lo procesa. ‘Auto’ usa la heurística por defecto (sizes con crop
   =true  uniforme; proporcional  proporcional; legacy/plugins viejos  omitir)” 
   ahora habla en idioma de usuario: “las imágenes pensadas para grilla (cuadradas)
   se uniforman; las pensadas para flujo (rectangulares) mantienen su proporción;
   las creadas por plugins antiguos que ya no usas se ignoran”. Misma lógica, vocabulario
   no-técnico. Footer del table también re-escrito.
 * **Bulk page — leds técnicos rewriteados estilo WP Rocket** — los tres helpers
   principales (header lede, “Generar muestra” lede, “Procesamiento masivo” lede
   + helper de cantidad) pasaron de mencionar “Action Scheduler”, “background”, “
   scope”, “bypasea”, “lotes de 5 cada 5 segundos” a explicaciones orientadas a 
   beneficios + caveats sin jargon: “corre en segundo plano — puedes cerrar esta
   página, el trabajo continúa solo”, “ignora tus filtros de Configuración a propósito”,“
   Cada una toma unos 5–15 segundos en alta calidad”.
 * **Catalog Watch — flujo 3-step explícito + tooltips** — los 3 botones “Escanear
   ahora” / “Vista previa de reparación” / “Aplicar reparación” ganaron tooltips
   per-botón explicando qué hace cada uno, y debajo del row hay un nuevo helper “
   Flujo recomendado: 1) Escanear para detectar problemas. 2) Vista previa para 
   ver qué se borraría (no modifica nada). 3) Aplicar para ejecutar la limpieza 
   cuando estés conforme”. El usuario ya no tiene que adivinar qué hace “vista previa”
   vs “aplicar”.

Internal: 296/296 unit tests passing. Plugin Check sobre v0.32.0 esperado 0 errors/
155 warnings (baseline S3 mantenido desde v0.23.14).

#### 0.31.0

Lote A — fix de 3 hallazgos P0 visuales de la prueba humana en drbrowns prod sobre
v0.30.0. Cero breaking changes — solo correcciones de layout y copy. Safe in-place
upgrade.

 * **Notice positioning fix** — agrega el marker `<hr class="wp-header-end" />` 
   después del header de cada admin page (10 pages: Dashboard, Configuración, Regenerar,
   Limpiar, Errores, Salud, Licencia, Multi-Site, CIT Cost, Catalog Watch). WordPress
   usa este marker para posicionar `admin_notices` correctamente; sin él, los notices
   del plugin (ej. `CatalogIssuesNotice` con 80892 issues) quedaban atravesados 
   visualmente entre el título y los badges de versión/estado.
 * **WP Customizer path correcto** — el copy del banner “Para que tus productos 
   se vean uniformes en la grilla” ahora muestra la ruta completa `Apariencia  Personalizar
   WooCommerce  Imágenes de producto  Cropping  1:1 (cuadrado)` en vez de la versión
   truncada anterior. Refleja la navegación real de WP-Admin para que el usuario
   encuentre el setting al primer intento.
 * **AI Alt Text section layout** — la sección “Alt text con IA” (Pro) ahora sale
   del grid `acimg-settings-layout` (TOC sticky + form 1fr) y se renderiza como 
   sibling `<div class="acimg-settings-aux">` debajo, con ancho completo y background
   blanco. Antes quedaba en el slot `__full` del grid pero el aside sticky de TOC
   la tapaba visualmente; también usaba clases huérfanas (`acimg-section`) que no
   existen en el CSS — ahora usa `acimg-surface` como el resto de cards de Settings,
   manteniendo coherencia visual.

Internal: 296/296 unit tests passing. Plugin Check sobre v0.31.0 esperado 0 errors/
155 warnings (baseline S3 mantenido desde v0.23.14).

#### 0.30.0

Final commercial-ready release — agrupa cierre del backlog perfeccionista post-audit
2026-05-25. Cero breaking changes acumulados entre v0.25  v0.30, todos los bumps
fueron polish + ADDs + transformations defensibles. Safe in-place upgrade.

 * **Re-capturados los 8 screenshots WP.org** (1200×900) con todo el polish aplicado:
   icon SVG header branded + TOC lateral sticky en Settings + upgrade card en License
   + KPI “Ahorro estimado” + 9 commands WP-CLI + 4 Pro pages funcionales. Los screenshots
   muestran al usuario potencial el estado real del plugin con polish post-v0.25.
 * **Skip jump v0.29.0** — version skip intencional para reflejar el major polish
   accumulated (v0.25  v0.30 incluye 5 bumps: v0.26 visual identity + v0.27 Settings
   TOC + v0.28 License upgrade + el cierre v0.30 con los screenshots updated + readme
   final).

Internal: 296/296 unit tests passing. Plugin Check sobre v0.30.0 esperado 0 errors/
155 warnings (baseline S3 mantenido desde v0.23.14, 6 meses estable).

#### 0.28.0

License page upgrade path (Sprint T4 direct, T-003 audit 2026-05-25). Cero breaking
changes — additions limpios.

 * **License page — upgrade path card** — converts the License page from “pure information”
   to “information + contextual actions”. When the user has a tier below Network,
   a new card appears below the existing license info showing upgrade options: tier
   name + sites count + Pro badge + CTA “Upgrade a X ” with direct deep link to 
   the Lemon Squeezy upgrade flow per tier. Mapping: Single  Studio + Agency / Studio
   Agency + Network / Agency  Network. Help text post-card explains “Lemon Squeezy
   issues your new license key instantly; apply the upgrade from this same page 
   by pasting the new key and activating”.
 * **Network tier max state** — when the user already has Network tier (top), the
   upgrade card is replaced by a “Tier máximo activo” card with `acimg-badge--pro`
   Network + thank-you message + “✉ Contactar soporte priority” CTA mailto link 
   to support@australcode.io.
 * **New utility CSS** `.acimg-upgrade-grid` + `.acimg-upgrade-card` — responsive
   grid layout (auto-fit, minmax 220px) collapsing to 1 column on mobile. Each card
   uses existing DS tokens (`--bg-surface`, `--border-default`, `--radius-md`, `--
   fs-15`, etc).

Internal: 296/296 unit tests passing. Plugin Check sobre v0.28.0 esperado 0 errors/
155 warnings (baseline S3 mantenido).

#### 0.27.0

Major UX upgrade for the Settings page (Sprint T1 mockup-first). Cero breaking changes—
el HTML interno de cada section se preserva exacto. Safe in-place upgrade.

 * **Settings page — lateral sticky TOC + smooth scroll** — the Configuration page
   used to be a 3500px linear scroll on mobile (10 sections back-to-back). Now there’s
   a sticky lateral navigation (left sidebar 200px desktop / `<select>` dropdown
   mobile) with smooth-scroll on click and IntersectionObserver-driven active state
   highlighting (the section currently centered in viewport gets accent bg in the
   TOC). Deep links to specific sections via URL hash also work (e.g. `#acimg-anchor-
   ai-alt-text` lands the user directly on AI Alt Text section). The Dashboard CTA
   card “Configurar ahora ” now lands precisely on the AI Alt Text section.
 * **DS integration** — the new layout uses tokens existing en `admin.css`: `--bg-
   surface`, `--border-default`, `--bg-selected`, `--accent-600`, `--radius-md`,`--
   radius-xs`. Sticky position with `top: 32px` offset for WordPress admin bar. 
   Max-height `calc(100vh - 64px)` con `overflow-y: auto` para sections muy largas.
   Section anchors (`.acimg-section-anchor`) usan `scroll-margin-top: 64px` para
   que el hash navigation no quede oculto bajo el admin bar.
 * **Mobile responsive** — el TOC sticky collapsa a `<select>` dropdown con label“
   Ir a sección…” cuando viewport ≤ 900px. Smooth scroll funciona igual.

Internal: 296/296 unit tests passing. Plugin Check sobre v0.27.0 esperado 0 errors/
155 warnings (baseline S3 mantenido). 1 nuevo asset JS encolado en Settings page(`
acimg-settings-toc`).

#### 0.26.0

Visual identity boost (Sprint H1 cross-leverage Bsale patterns). Cero breaking changes,
cero migrations — safe in-place upgrade.

 * **Branded icon SVG in admin page header** — every admin page now displays the
   plugin’s mark icon (Concept C — image inscribed in a canvas) on the left side
   of the title, with accent color and a subtle background. Applied via CSS pseudo-
   element so all 15+ page header occurrences benefit automatically without per-
   page changes. Cross-leverage pattern from `australcode-bsale` (audit familia 
   2026-05-26).
 * **Highlighted CTA card for Pro features needing configuration** — when the user
   has Pro license active but AI Alt Text is not configured, the Dashboard now shows
   a left-accent CTA card guiding them to “Configurar ahora ” with a deep link to
   the Settings AI Alt Text section. Reduces silent friction where the user pays
   Pro and doesn’t find how to activate the feature.
 * **DashboardPage constructor** — 2 new deps autowired by `League\Container`: `
   LicenseGate` + `AiConfigRepository` (both already registered in the container,
   zero migration impact).

Internal: 296/296 unit tests passing. Plugin Check sobre v0.26.0 esperado 0 errors/
155 warnings (baseline S3 mantenido).

#### 0.25.0

Transformations ADDs (no breaking changes, no migrations) — Sprint E del backlog
post-v0.24.0 audit 2026-05-25.

 * **New (Dashboard) — KPI “Ahorro estimado” en hero** — un 5to KPI card al lado
   de “Ahorro al servir AVIF (%)” ahora muestra el ahorro **en bytes humanos** (
   ej. “50 MB”). Heurística: `sum(original_bytes - avif_bytes)` over all processed
   attachments, asume ~99.5% visitors compatibles con AVIF (default 2026). Convierte
   el dashboard de “estado” a “valor demostrado” — el usuario ve cuánto le ahorró
   el plugin en cifras concretas, no solo en %.
 * **Documented (Settings) — modal pre-save “Esto invalidará N derivados”** — el
   modal ya existía desde v0.23.x pero no estaba destacado en el listing. Ahora 
   documentado: al click “Guardar configuración” con cambios que afectan el `pipeline_hash`(
   padMode, padColor, trim, quality preset, AVIF speed, formats enabled, etc.), 
   aparece dialog con: count de derivados a invalidar, bytes en storage, lista exacta
   de campos que cambiaron, link a “Regenerar en lote” para reconstruir, opciones“
   Cancelar” / “Guardar de todos modos”. Cero sorpresa para el usuario al cambiar
   settings.

Internal: 296/296 unit tests passing. Plugin Check sobre v0.25.0 esperado 0 errors/
155 warnings (baseline S3 mantenido). El método privado `estimateSavings()` en `
DashboardPage` retorna un campo nuevo `bytes_saved` además de los existentes (sin
breaking changes — campos viejos preservados).

#### 0.24.1

Polish + DS coherence pass — no functional changes, no migrations, safe in-place
upgrade.

 * **Polish — status indicators** — 6 emoji occurrences in admin UI (white check,
   warning, red circle, lock) replaced with the canonical `.acimg-dot--*` color-
   coded indicators. Reasons: cross-OS rendering consistency, no impact on flex/
   grid alignment, screen reader friendlier (no “white heavy check mark” noise).
   Affected: Settings flash notice, Catalog Watch issues empty state, Multi-Site
   issues column + help list.
 * **Polish — admin copy es-CL canonical** — 8 strings switched from hybrid EN/ES
   to neutral Chilean Spanish: “Vista previa heal”  “Vista previa de reparación”,“
   Aplicar heal”  “Aplicar reparación”, “Auto-Heal”  “Auto-reparación”, “Sync all”“
   Sincronizar todos”, “Refresh ahora”  “Refrescar ahora”, “Sample test”  “Generar
   muestra” (3 occurrences in Dashboard).
 * **Polish — voseo cleanup** — `wp acimg purge-cache --all` confirmation prompt
   no longer uses Rioplatense “CONFIRMÁS”. Now says “¿Confirmas borrar TODOS los
   derivados?”.
 * **DS — `.acimg-btn--loading` utility** added in `assets/css/admin.css`. Spinner
   reusable for any AJAX button (reuses existing `@keyframes acimg-spin`). Companion
   helper `acimgWithLoading(btn, asyncFn)` exposed globally via the new `assets/
   js/btn-loading.js` (always enqueued on plugin pages).
 * **DS — `surface` vs `card` convention** documented inline in `admin.css` to prevent
   drift. `.acimg-surface` = main section with `<h2>` visible. `.acimg-card` = banner/
   sub-content / status panel without title.
 * **CLI — `wp acimg purge-cache --dry-run` flag** added as explicit alias of the
   safe default behavior (mutually exclusive with `--yes`). Aligns with standard
   WP-CLI convention for destructive commands.
 * **Docs — readme accurately lists 9 WP-CLI commands** (previously said 8, missing`
   wp acimg reset` which resets all persisted plugin state without deactivating).
   FAQ entry expanded with the same correction.

Internal: 296/296 unit tests passing. Plugin Check 0 errors, 155 warnings (S3 baseline
maintained).

#### 0.24.0

 * **New (Pro) — AI Alt Text admin UI** — the BYOK alt text generation feature (
   OpenAI gpt-4o-mini / Anthropic claude-haiku-4-5) now has three dedicated UI surfaces:
    - **Settings  “Alt text con IA”** section: provider select, masked API key field,
      language picker, “Save” + “Generate test” buttons that hit `/alt-text/generate/
      <lastAttachmentId>` with `apply: false` for instant preview.
    - **Attachment editor  “Alt text con IA”** field: “Generate with AI” button 
      next to the native Alt text field; preview before apply; one click fills the
      native field. Works in `post.php?action=edit` and the media modal.
    - **Media library bulk action**: “Generate alt with AI” entry in `upload.php?
      mode=list` bulk dropdown; processes selected attachments in batches of 5 with
      anti-rate-limit pacing (OpenAI 10rpm tier 1 / Anthropic 50rpm).
 * All three surfaces are gated server-side (Pro license active + AI config present
   + `manage_woocommerce` capability) and gracefully hide for Free users.
 * **Fix (P0 WP.org compliance)** — `uninstall.php` cleanup query was matching the
   legacy `pir_` prefix instead of the current `acimg_` after the rebrand, leaving
   up to 8 options (including encrypted license key and AI API key) residual in 
   the DB after uninstall. Now matches `acimg_%` correctly.
 * **Fix (P0 mobile polish)** — format chips (JPEG / WebP / AVIF) in the Dashboard“
   Configuración actual” card were breaking across two lines on mobile (“JPE G” /“
   WEB P” / “AVI F”) because `.acimg-chip` had no `white-space: nowrap`. Now chips
   stay on one line and wrap to a new row only if there isn’t enough horizontal 
   space.
 * **Fix (CLI copy)** — `wp acimg regenerate` dry-run success message used a Rioplatense
   Spanish conjugation (“pasá”) instead of neutral Chilean Spanish (“pasa”). Corrected.
 * **Fix (defensive)** — `Dashboard::sumOriginalBytesProcessed()` now uses `unserialize(
   $x, ['allowed_classes' => false])` for `_wp_attachment_metadata` parsing, matching
   the defensive pattern already in `SirMigrator` and `MediaAuditController` (regression:
   1 of 7 occurrences was missing the guard).

#### 0.23.17

 * **Fix (admin UI)** — info bars and notices no longer render with their text glued
   to the edges. The `.acimg-card` callout had no padding defined, and the `.acimg-
   notice` component carried a leftover `::before` accent with negative margins 
   that didn’t match the padding. Both are now consistent (proper padding + a single
   clean left accent).

#### 0.23.16

 * **Fix (Catalog Watch)** — the “Preview heal” and “Apply heal” buttons always 
   showed “Error: desconocido” even when the server responded successfully: the 
   JavaScript read the success/summary fields off the fetch wrapper object instead
   of the response body. Both handlers now unwrap the response correctly, so the
   preview/apply report real counts. Scale-independent fix (affected every site).

#### 0.23.15

 * **CLI/UI polish** — user-facing references to the CLI command corrected from 
   the legacy `wp pir` to `wp acimg` across `wp help` output, admin hints, and inline
   docs (the command was already registered as `acimg`, so the old examples pointed
   at a non-existent command).
 * **Fix** — the first-run onboarding wizard derived its nonce and “completed” flag
   out of scope, which caused a 403 on the onboarding REST calls and made the wizard
   re-appear on every Settings visit; both are now derived within the section that
   renders the wizard.
 * **i18n** — translation catalog synced with the renamed CLI references.

#### 0.23.14

 * **WordPress.org compliance (Plugin Check)** — addressed the official Plugin Check
   errors: `Tested up to` bumped to 7.0; direct filesystem calls migrated to WordPress
   wrappers (`wp_delete_file`, `WP_Filesystem`, `wp_is_writable`); SQL queries hardened(`%
   i` for internal table identifiers, `LIKE` wildcards passed as prepared parameters
   with `esc_like`); `$_GET` input properly unslashed/sanitized.
 * **External services disclosure** — added an “External services” section to the
   readme documenting Lemon Squeezy (license), OpenAI/Anthropic (AI Alt Text, BYOK),
   and Cloudflare (Image Transformations + Analytics): what data is sent, when, 
   and links to each provider’s terms and privacy policy.
 * **Branding consistency** — user-facing references to the old menu name updated
   to “Australcode Image”; landing URLs unified to the canonical domain; `wp help
   acimg`.
 * **Fix** — uninstall now removes the plugin’s Action Scheduler actions using the
   current `acimg_` hook prefix (previously used the old prefix and left orphan 
   rows).

#### 0.23.13

 * **WP.org compliance (enqueue)** — all 12 inline `<script>`/`<style>` blocks in
   admin pages and notices migrated to `wp_enqueue_script`/`wp_enqueue_style` with`
   wp_localize_script` for dynamic data. No behavior change; assets now load through
   the WordPress Scripts/Styles API. The HTML email `<style>` (HealthEmailFormatter)
   remains inline by necessity (email clients).

#### 0.23.12

 * **UX/UI deep audit follow-up** — 11 findings addressed (0 P0, 5 P1, 4 P2, 2 P3).
 * **Human-readable durations**: scan durations show “12 min 7 s” instead of raw“
   726.896 s”. New `DurationFormatter`.
 * **Async scan reassurance**: Catalog Watch shows a banner during a running scan(“
   runs in background, you can close this window”) with human status copy. Progress
   was always preserved server-side via Action Scheduler; now the UI says so.
 * **Prominent cleanup CTA**: Dashboard “Storage recuperable” clean-up is now a 
   button with the amount in the label (“Limpiar 3,19 GB ”) instead of a tiny 11px
   link.
 * **License badges fixed**: status badges referenced 3 non-existent CSS classes(
   fell back to grey); added semantic aliases (`--success`/`--danger`/`--neutral`).
 * **Voseo cleanup**: removed the 10 remaining rioplatense conjugations the v0.23.7
   pass missed.
 * **Token migration**: Media Cleanup’s 40 hardcoded hex  design-system tokens (
   dark-mode-ready); Health cron timestamps in site timezone instead of raw GMT;
   status emojis in tables  semantic dots; remaining English labels translated (
   CIT Cost, Catalog Watch headers).

#### 0.23.11

 * **Catalog Watch v2 + stale storage cleanup**: new `StaleDerivative` detector 
   finds rows in `wp_pir_derivatives` whose `pipeline_hash` no longer matches the
   current settings hash. Storage reclaimable is reported in Dashboard, Catalog 
   Watch and Bulk Regen pages. Auto-Healer supports stale removal (Pro feature) —
   orphans/ghosts remain Free as they are corruption repair, not storage optimization.
 * **Dashboard “Storage recuperable” KPI**: permanent card showing reclaimable GB/
   MB + count of stale derivatives. If clean, shows “Catálogo limpio” with success
   indicator. Links to Catalog Watch for cleanup action.
 * **Catalog Watch scan now async**: `/catalog-watch/scan` returns 202 + `job_id`
   and enqueues Action Scheduler. Frontend polls `/scan-status`. Fixes timeout on
   sites with >1000 attachments (Cloudflare 100s limit returned HTML 524 instead
   of JSON).
 * **Health page Catalog Watch cron row**: new row showing the next scheduled run
   + last completed time + status indicator. Helps diagnose if the daily cron is
   properly scheduled (Pro), failed last run, or wasn’t scheduled at all.
 * **License activation hook**: when activating a license via REST `/license/activate`,
   the plugin now fires `do_action('pir_license_activated')` so other Pro features
   can initialize side-effects (like scheduling the Catalog Watch daily cron) without
   waiting for the next admin page load. Fixes the case where a fresh install with
   license activated later had the daily cron unscheduled.
 * **WP-CLI gate refinement**: `wp acimg purge-cache --orphans` is now Free (corruption
   repair). `--stale` and `--all` remain Pro (storage optimization).

#### 0.23.10

 * **Onboarding wizard error handling**: when the `/onboarding/apply` REST endpoint
   returns an error (expired nonce, missing capability, security plugin interception),
   the wizard now shows an inline red error message in step 2 and restores the button
   instead of silently jumping to the “Configuration applied” screen. Fixes a UX
   bug where users could see a success message even though the configuration was
   not saved.
 * **JS API wrapper hardened**: new `apiCheck()` helper validates HTTP status + 
   parses JSON body + returns structured `{ ok, data, error }`. Replaces raw `fetch().
   then(r => r.json())` pattern that did not differentiate between success and error
   responses (fetch only throws on network errors, not on HTTP 4xx/5xx).
 * **Test coverage**: new `OnboardingControllerTest` locks the WP_Error contract(
   code, message, data.status) that the wizard JS depends on. Future WP API changes
   that break the shape will be caught at test time.

#### 0.23.9

 * **Uniform-by-default for all image sizes**: Plugin now uniforms every registered
   size to its declared dimensions by default, regardless of the WP `crop` flag.
   Before 0.23.9, sizes with `crop=false` (`medium_large`, `woocommerce_single`,`
   large`) were left Proportional, producing rectangular derivatives that broke 
   the “uniform images without crop” promise. Override per-size with `sizesConfig[
   <size>] = "proportional"`.
 * **First-visit onboarding wizard**: detects WooCommerce `thumbnail_cropping` +
   registered sizes and applies the recommended config (all uniform) in one click.
 * **Health check**: WooCommerce thumbnail cropping (1:1 / custom / uncropped) reported
   in Health page + dismissible notice when misaligned.
 * **Content target default** changed 100  85 (15% breathing space, more premium).
   Existing installs keep their value.
 * **Action required after upgrade**: run a Bulk Regen to regenerate derivatives
   with the new uniform default.

Full history of older versions (0.23.8 and earlier) is preserved in the project’s
archive — contact support@australcode.io if you need detail on a specific legacy
version.

## Meta

 *  Version **0.37.0**
 *  Last updated **3 hours ago**
 *  Active installations **Fewer than 10**
 *  WordPress version ** 6.5 or higher **
 *  Tested up to **7.0**
 *  PHP version ** 8.2 or higher **
 * Tags
 * [AVIF](https://wordpress.org/plugins/tags/avif/)[image resize](https://wordpress.org/plugins/tags/image-resize/)
   [product images](https://wordpress.org/plugins/tags/product-images/)[thumbnails](https://wordpress.org/plugins/tags/thumbnails/)
   [woocommerce](https://wordpress.org/plugins/tags/woocommerce/)
 *  [Advanced View](https://wordpress.org/plugins/australcode-uniform-images/advanced/)

## Ratings

No reviews have been submitted yet.

[Your review](https://wordpress.org/support/plugin/australcode-uniform-images/reviews/#new-post)

[See all reviews](https://wordpress.org/support/plugin/australcode-uniform-images/reviews/)

## Contributors

 *   [ australcode ](https://profiles.wordpress.org/australcode/)

## Support

Got something to say? Need help?

 [View support forum](https://wordpress.org/support/plugin/australcode-uniform-images/)