PHPackages                             brocode/module-image-optimizer - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Image &amp; Media](/categories/media)
4. /
5. brocode/module-image-optimizer

ActiveMagento2-module[Image &amp; Media](/categories/media)

brocode/module-image-optimizer
==============================

Magento2 Module to search for certain specified image files for conversion to other formats

1.1.1(1mo ago)07463MITPHP

Since Jun 29Pushed 2w ago1 watchersCompare

[ Source](https://github.com/brosenberger/module-image-optimizer)[ Packagist](https://packagist.org/packages/brocode/module-image-optimizer)[ Fund](https://www.buymeacoffee.com/brosenberger)[ RSS](/packages/brocode-module-image-optimizer/feed)WikiDiscussions main Synced 2d ago

READMEChangelogDependencies (2)Versions (4)Used By (3)

Image Optimizer Base - a Magento 2 setup for image optimizations
================================================================

[](#image-optimizer-base---a-magento-2-setup-for-image-optimizations)

> 📖 **Full docs, design notes &amp; production guidance:**[brocode.at/modules/module-image-optimizer](https://brocode.at/modules/module-image-optimizer/)Part of the BroCode Image Optimizer family for Magento 2.

This module should ease the way of adding new image formats to a Magento 2 shop without the need of adapting any templates or markups.

**Goals of this module:**

- Base scanner of folders for images which might need to be served in modern formats (e.g. /pub/media)
- Framework for adding various different converter to be extendable for any new future image formats

[!["Buy Me A Coffee"](https://camo.githubusercontent.com/9f44ce2dc3b3eecdd02598900866ffc518801df1932849703dae1e5ce5031070/68747470733a2f2f7777772e6275796d6561636f666665652e636f6d2f6173736574732f696d672f637573746f6d5f696d616765732f6f72616e67655f696d672e706e67)](https://www.buymeacoffee.com/brosenberger)

Requirements
------------

[](#requirements)

- Magento 2.4.x
- Web server: **nginx** (the only server Adobe supports from 2.4.9; nginx 1.30). Apache config is included for older installs, but Apache was dropped from Magento's tested requirements at 2.4.8-p3 / 2.4.7-p7.
- PHP 8.3 / 8.4 (8.5 on 2.4.9)

Installation
------------

[](#installation)

```
composer require brocode/module-image-optimizer
bin/magento module:enable BroCode_ImageOptimizer
bin/magento setup:upgrade

```

Idea on how to delivery optimized images in a Magento 2 shop (or any other system)
----------------------------------------------------------------------------------

[](#idea-on-how-to-delivery-optimized-images-in-a-magento-2-shop-or-any-other-system)

Magento 2 is slow when delivering anything where a PHP process is involved in comparison to a simple file transfer for any file directly servable via the web server. This can be utilized to separate the conversion of the optimized images and serving them.

1. The conversion takes place within the Magento2 environment (or any other) to determine which files need conversion and to which file they should be converted to.
2. The webserver utilizes internal rewrites and file checks which file needs to be served, based on the request of the user agent (browser Accept-Header).

Converted files are stored next to the original with a suffix (e.g. `photo.jpg.webp`). Configure the web server to serve that sidecar when the client accepts the format.

New Magento installations use **nginx**; Apache `.htaccess` remains for legacy setups.

### Nginx (recommended)

[](#nginx-recommended)

Add to the shop vhost (see Magento `nginx.conf.sample`). Place the `map` in `http {}`. Add the `location` before the generic static file location under `location /media/ {}` so it takes precedence.

```
# In http { } (once per nginx instance or included vhost file)
map $http_accept $webp_suffix {
    default "";
    "~*webp" ".webp";
}

# In server { }
location ~* ^/media/.+\.(png|gif|jpe?g)$ {
    add_header Vary Accept;
    try_files $uri$webp_suffix $uri $uri/ /get.php$is_args$args;
}

```

- `map` sets `$webp_suffix` to `.webp` when the browser sends `Accept: image/webp`
- `try_files` serves `photo.jpg.webp` when it exists, otherwise the original raster file
- `/get.php` fallback keeps Magento catalog image generation working for missing cache files
- `Vary: Accept` helps CDNs and browsers cache WebP and non-WebP responses separately

### Apache (legacy)

[](#apache-legacy)

Add to `pub/media/.htaccess` to deliver WebP images when they exist:

```
 ############################################
 ## if client accepts webp, rewrite image urls to use webp version
AddType image/webp .webp
RewriteCond %{HTTP_ACCEPT} image/webp
RewriteCond %{REQUEST_FILENAME} (.*)\.(png|gif|jpe?g)$
RewriteCond %{REQUEST_FILENAME}\.webp -f
RewriteRule ^ %{REQUEST_FILENAME}\.webp [L,T=image/webp]

```

- register the WebP mime type
- check if the browser accepts WebP
- check if the requested file is png, gif, or jpeg
- check if a `.webp` sidecar exists for the requested file
- rewrite the request to the WebP file

The same pattern applies to other formats (e.g. AVIF — see `brocode/module-image-optimizer-avif`).

Features
--------

[](#features)

### Cronjob for folder scanning of images

[](#cronjob-for-folder-scanning-of-images)

Scans all configured image folders, can be disabled via configuration.

**Configuration**

The cronjob can be disabled under `Stores -> Configuration -> Services -> BroCodeI ImageOptimizer`, it is enabled per default.

**Image Paths**

The ImagePathScannerService recieves via dependency injection `BroCode\ImageOptimizer\Api\Data\ImagePathProviderInterface` which can provide any directory to be scanned.

```

            BroCode\ImageOptimizer\Model\Data\XmlConfigurableImagePathProvider

```

One default path provider is implemented, which takes arguments via di.xml. The current setting is for the pub/media folder, the Magento base folder is added automatically to every entry given:

```

            pub/media

```

### CLI commands

[](#cli-commands)

Images Scanning (same function as cronjob + listing possibility of images to be optimized):

```
bin/magento images:optimize:scan

```

**Options:**

- `-l | --list`: List all images that need to be optimized, file is stored in `var/_image_optimizer.log`

### Conversion Hooks

[](#conversion-hooks)

This module provides an event hook for every image that needs to be converted. This is implemented with an default Magento 2 event and can be utilized with an observer listening on the event `brocode_convert_image`. The event has following data stored that can be used:

```
$this->eventManager->dispatch(
    'brocode_convert_image',
    [
        'image_path' => $file->getPathname(),
        'converter_id' => $imageConvertValidator->getConverterId()
    ]
);
```

**Convert Validator**

A convert validator checks if a given found image in any configured path needs conversion and which converter might be used for it. Every validator must implement `BroCode\ImageOptimizer\Api\Data\ImageConvertValidationInterface`. A base implementation for file checks is implemented in the abstract class `BroCode\ImageOptimizer\Model\Converter\AbstractImageConverter`.

These converter validator need to be contributed via di.xml to the `\BroCode\ImageOptimizer\Model\ImageConverterService`:

```

        ...

            BroCode\ImageAvifOptimizer\Model\Converter\AvifImageConverter

```

### Image conversion

[](#image-conversion)

There is currently no image conversion implemented in this module, this is done with following two basic modules:

- **brocode/module-image-optimizer-avif** (for AVIF generation)
- **brocode/module-image-optimizer-webp** (for WEBP generation)

Though there is the default `BroCode\ImageOptimizer\Observer\InstantConvertImageObserver` which catches the conversion event and try to convert the image with the help of any converter contributed to the `\BroCode\ImageOptimizer\Model\ImageConverterService`:

```

            BroCode\ImageAvifOptimizer\Model\Converter\AvifImageConverter

        ...

```

**This is done synchronously and slows down the according cron execution, especially if there are many images.**

Consider using the extensions for the usage of the Magento 2 queue system to asynchronously process image conversion:

- **brocode/module-image-optimizer-queue** (default MySQL queue for shops without active RabbitMQ installations)
- **brocode/module-image-optimizer-amqp** (extension to the queue module for configurations of the RabbitMQ services)

Change Log
----------

[](#change-log)

**1.1.1**

- Document nginx WebP serving in README (Apache remains documented for legacy setups)

**1.1.0**

- Moved image path provider to service instead of cron job
- added CLI command to scan/optimize images + listing of images to be optimized

**1.0.0**

- Initial version

Module family
-------------

[](#module-family)

ModulePurpose[module-image-optimizer](https://github.com/brosenberger/module-image-optimizer)Base: scan `pub/media`, write modern-format sidecars[module-image-optimizer-webp](https://github.com/brosenberger/module-image-optimizer-webp)WebP converter[module-image-optimizer-avif](https://github.com/brosenberger/module-image-optimizer-avif)AVIF converter[module-image-optimizer-queue](https://github.com/brosenberger/module-image-optimizer-queue)Async conversion via the Magento queue[module-image-optimizer-amqp](https://github.com/brosenberger/module-image-optimizer-amqp)Async conversion over RabbitMQ/AMQPDocs &amp; guides: **[brocode.at](https://brocode.at/modules/module-image-optimizer/)**

###  Health Score

44

—

FairBetter than 90% of packages

Maintenance94

Actively maintained with recent releases

Popularity17

Limited adoption so far

Community15

Small or concentrated contributor base

Maturity43

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 90.9% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~348 days

Total

3

Last Release

39d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/9453d161c28a18e817351e00d7ebe81ada31842a249ffb3389830b3483584e60?d=identicon)[brosenberger](/maintainers/brosenberger)

---

Top Contributors

[![rosenberger-e-conomix](https://avatars.githubusercontent.com/u/47806105?v=4)](https://github.com/rosenberger-e-conomix "rosenberger-e-conomix (10 commits)")[![brosenberger](https://avatars.githubusercontent.com/u/2969243?v=4)](https://github.com/brosenberger "brosenberger (1 commits)")

---

Tags

image-optimisationmagento2-module

### Embed Badge

![Health badge](/badges/brocode-module-image-optimizer/health.svg)

```
[![Health](https://phpackages.com/badges/brocode-module-image-optimizer/health.svg)](https://phpackages.com/packages/brocode-module-image-optimizer)
```

###  Alternatives

[fastly/magento2

Fastly CDN Module for Magento 2.4.x

1564.4M1](/packages/fastly-magento2)[yireo/magento2-next-gen-images

Magento 2 module to add NextGen images support to the Magento frontend

471.2M2](/packages/yireo-magento2-next-gen-images)[checkoutcom/magento2

Checkout.com Payment Gateway for Magento 2

34276.3k1](/packages/checkoutcom-magento2)[myparcelnl/magento

A Magento 2 module that creates MyParcel labels

1860.2k](/packages/myparcelnl-magento)[elgentos/magento2-imgix

Imgix extension for Magento 2 to process images

1670.0k](/packages/elgentos-magento2-imgix)[mage-os/module-automatic-translation

Automatic AI content translation for Mage-OS.

3017.9k](/packages/mage-os-module-automatic-translation)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
