Image Resizer Extension
The Magebit Image Resizer Extension allows Magento 2 developers to effortlessly resize images programmatically, boosting website performance and improving user experience. This extension seamlessly integrates into projects, saving time and effort in managing visual assets.
Overview
The Image Resizer Extension provides comprehensive image processing capabilities for Magento 2, enabling developers to resize, transform, and optimize images with advanced features like watermarks, rotation, and responsive image generation.
Main Functionalities
Core Image Processing
- Image Sources - Work with images from
pub/mediaandmodulefolders - Configuration - Configuration from view.xml and programmatic settings
- Resize Operations - Resize images with various constraints and options
Advanced Features
- Object-Fit Cover - Apply CSS object-fit: cover for images
- Constraints - Keep constrain, frame, and aspect ratio settings
- Transformations - Rotate images to specified angles
- Background - Set custom background colors
- Watermark - Apply watermarks with position and opacity control
- Quality Control - Adjust image quality settings
- Placeholder Support - Use placeholder images when needed
Installation
Install the Image Resizer extension using Composer.
Installation Command:
composer require magebitcom/magento2-image-resizerPost-Installation Steps:
bin/magento setup:upgradeUsage
View Models
The extension provides two main view models for different use cases:
ImageResizer: Main resizing entrance for daily use with comprehensive image processing capabilities.
CategoryImageResizer: Extends ImageResizer with additional methods to pass category-specific parameters.
Basic Usage
File Path Formats: File paths can be specified in two formats:
- Pub Media Path:
style-guide/test1.jpg- located inpub/media/style-guide/test1.jpg - Module Asset:
Magebit_StyleGuide::images/test1.jpg- located in module's web directory
Basic Resizing Examples:
Image from pub/media directory:
<?php
$imageResizerViewModel = $viewModels->require(ImageResizer::class);
?>
<img src="<?= $escaper->escapeUrl($imageResizerViewModel
->init('style-guide/test1.jpg')
->resize(400, 200)
->getUrl()) ?>"/>Image from module asset:
<?php
$imageResizerViewModel = $viewModels->require(ImageResizer::class);
?>
<img src="<?= $escaper->escapeUrl($imageResizerViewModel
->init('Magebit_StyleGuide::images/test1.jpg')
->resize(400, 200)
->getUrl()) ?>"/>Flexible Resizing (width or height only):
<?php
$imageResizerViewModel = $viewModels->require(ImageResizer::class);
?>
<!-- Height only (width will match) -->
<img src="<?= $escaper->escapeUrl($imageResizerViewModel
->init('Magebit_StyleGuide::images/test2.jpg')
->resize(height: 200)
->getUrl()) ?>"/>
<!-- Width only (height will match) -->
<img src="<?= $escaper->escapeUrl($imageResizerViewModel
->init('Magebit_StyleGuide::images/test2.jpg')
->resize(width: 200)
->getUrl()) ?>"/>Category Image Usage
Use the specialized CategoryImageResizer for category-specific image processing:
<?php
$categoryImageResizerViewModel = $viewModels->require(CategoryImageResizer::class);
?>
<img src="<?= $categoryImageResizerViewModel
->category(20)
->resize(300, 200)
->keepFrame(true)
->getUrl(); ?>"/>Category Method Parameters:
int|CategoryInterface $category- Category ID or category modelstring $imageAttribute- Image attribute (default: image)string $imageId- Image IDarray $attributes- Additional attributes
Responsive Picture Generation
Generate responsive picture tags with sources for Desktop and Mobile using getResponsivePicture:
<?php
$imageResizerViewModel = $viewModels->require(ImageResizer::class);
?>
<?= $imageResizerViewModel
->constrainOnly(false)
->keepAspectRatio(false)
->keepFrame(false)
->getResponsivePicture(
$block->getImagePath(),
null,
[
'alt' => $escaper->escapeHtmlAttr($category->getName()),
'aria-label' => $escaper->escapeHtmlAttr($category->getName()),
'class' => 'hidden lg:block image object-cover',
'picture_class' => 'flex'
],
'category_block_list_widget',
['width' => 170, 'height' => 120],
null
); ?>Responsive Picture Features:
- Generates sources with original and WebP format
- Supports desktop/mobile and retina screens
- Automatically adds
_mobilesuffix for mobile image IDs - Uses desktop path for mobile if mobile path not provided
- Generates mobile sources only if size differs
Responsive Picture with ImageId
Using ImageId from view.xml:
<?php
$imageResizerViewModel = $viewModels->require(ImageResizer::class);
?>
<?= $imageResizerViewModel
->keepAspectRatio(false)
->constrainOnly(true)
->backgroundColor([0, 0, 0])
->getResponsivePicture(
"Magebit_StyleGuide::images/test2.jpg", // Desktop image
"Magebit_StyleGuide::images/test1.jpg", // Mobile image
['class' => 'mt-5'], // HTML attributes
'category_block_list_widget' // ImageId from view.xml
); ?>Without Mobile Image (Single Version):
<?php
$imageResizerViewModel = $viewModels->require(ImageResizer::class);
?>
<?= $imageResizerViewModel
->keepAspectRatio(false)
->constrainOnly(true)
->backgroundColor([0, 0, 0])
->getResponsivePicture(
"Magebit_StyleGuide::images/test2.jpg", // Desktop image
null, // No mobile image
['class' => 'mt-5'], // HTML attributes
null, // No imageId
['width' => 768, 'height' => 480] // Custom dimensions
); ?>Tablet tier and custom breakpoints
Image Resizer 0.1.14
The tablet tier, configurable breakpoints, and getResponsiveSources() below ship in Image Resizer 0.1.14, the version bundled with Venta 1.6.4.
getResponsivePicture() accepts optional trailing parameters for a third (tablet) tier and custom breakpoints:
?string $tabletUrland?array $tabletSizeadd a tablet<source>between mobile and desktop. When only a size or a_tabletimage id is given, the desktop URL is reused.- A matching
_tabletimage id inview.xmlis resolved automatically, in the same way_mobilealready is. int $mobileMaxWidth(default767) andint $tabletMaxWidth(default1024) set the breakpoints, so they are no longer fixed.int $mobileMinWidthandint $tabletMinWidth(default0) make a tier use a rangedmin-width/max-widthmedia query when set above zero. Tiers render narrowest first.
Responsive sources for client-side rebuilds
getResponsiveSources() returns the same responsive data as a structured array instead of HTML, so a script can rebuild the mobile/tablet/desktop sources on the client (for example after a swatch swap):
$sources = $imageResizerViewModel
->getResponsiveSources(
'Magebit_StyleGuide::images/test2.jpg', // image path
'product_card', // imageId from view.xml (uses its _mobile / _tablet variants)
['width' => 288, 'height' => 288] // desktop size
);
// [
// 'sources' => [ ['media' => ..., 'type' => ..., 'srcset' => ..., 'width' => ..., 'height' => ...], ... ],
// 'img' => ['src' => ..., 'width' => ..., 'height' => ...],
// ]It derives the mobile and tablet tiers from the image id's _mobile / _tablet variants and takes the same breakpoint parameters as getResponsivePicture(). The isObjectFitCover() accessor reports whether the store crops images to fill by default (the object_fit_cover setting), which is useful when deciding how to render a rebuilt source.
Advanced Usage Examples
Aspect Ratio Control
Maintain Original Aspect Ratio:
<?php
$imageResizerViewModel = $viewModels->require(ImageResizer::class);
?>
<!-- Aspect ratio = true (default) -->
<img src="<?= $escaper->escapeUrl($imageResizerViewModel
->init('Magebit_StyleGuide::images/test3.jpg')
->resize(100, 300)
->keepAspectRatio(true)
->getUrl()) ?>"/>
<!-- Aspect ratio = false (distorted) -->
<img src="<?= $escaper->escapeUrl($imageResizerViewModel
->init('Magebit_StyleGuide::images/test3.jpg')
->resize(100, 300)
->keepAspectRatio(false)
->getUrl()) ?>"/>Constrain and Frame Options
Constrain Only (Prevent Upscaling):
<?php
$imageResizerViewModel = $viewModels->require(ImageResizer::class);
?>
<!-- Constrain only = true (won't exceed original size) -->
<img src="<?= $escaper->escapeUrl($imageResizerViewModel
->init('Magebit_StyleGuide::images/test2.jpg')
->resize(800)
->constrainOnly(true)
->backgroundColor([0, 0, 0])
->getUrl()) ?>"/>
<!-- Constrain only = false (can exceed original size) -->
<img src="<?= $escaper->escapeUrl($imageResizerViewModel
->init('Magebit_StyleGuide::images/test2.jpg')
->resize(800)
->constrainOnly(false)
->backgroundColor([0, 0, 0])
->getUrl()) ?>"/>Frame Control:
<?php
$imageResizerViewModel = $viewModels->require(ImageResizer::class);
?>
<!-- Frame = true (exact dimensions with background) -->
<img src="<?= $escaper->escapeUrl($imageResizerViewModel
->init('Magebit_StyleGuide::images/test2.jpg')
->resize(800)
->keepFrame(true)
->backgroundColor([0, 0, 0])
->getUrl()) ?>"/>
<!-- Frame = false (natural dimensions) -->
<img src="<?= $escaper->escapeUrl($imageResizerViewModel
->init('Magebit_StyleGuide::images/test2.jpg')
->resize(800)
->keepFrame(false)
->backgroundColor([0, 0, 0])
->getUrl()) ?>"/>Object-Fit Cover
CSS Object-Fit Behavior:
<?php
$imageResizerViewModel = $viewModels->require(ImageResizer::class);
?>
<img src="<?= $escaper->escapeUrl($imageResizerViewModel
->init('Magebit_StyleGuide::images/test2.jpg')
->resize(800, 200)
->setObjectFit(true)
->getUrl()) ?>"/>Quality Control
Custom Image Quality:
<?php
$imageResizerViewModel = $viewModels->require(ImageResizer::class);
?>
<img src="<?= $escaper->escapeUrl($imageResizerViewModel
->init('Magebit_StyleGuide::images/test2.jpg')
->quality(1) // Very low quality for demonstration
->getUrl()) ?>"/>Image Rotation
Rotate Images:
<?php
$imageResizerViewModel = $viewModels->require(ImageResizer::class);
?>
<img src="<?= $escaper->escapeUrl($imageResizerViewModel
->init('Magebit_StyleGuide::images/test2.jpg')
->rotate(90) // Rotate 90 degrees
->getUrl()) ?>"/>Background Colors
Custom Background Colors:
<?php
$imageResizerViewModel = $viewModels->require(ImageResizer::class);
?>
<img src="<?= $escaper->escapeUrl($imageResizerViewModel
->init('Magebit_StyleGuide::images/test1.jpg')
->resize(200, 200)
->backgroundColor([255, 0, 255]) // Magenta background
->keepFrame(true)
->getUrl()) ?>"/>Placeholder Images
Custom Placeholders:
<?php
$imageResizerViewModel = $viewModels->require(ImageResizer::class);
?>
<!-- Default catalog placeholder -->
<img src="<?= $escaper->escapeUrl($imageResizerViewModel
->init('non_existing_image_path')
->getUrl()) ?>"/>
<!-- Custom placeholder -->
<img src="<?= $escaper->escapeUrl($imageResizerViewModel
->init('non_existing_image_path')
->placeholder('Magebit_StyleGuide::images/test4.png')
->getUrl()) ?>"/>Watermark Application
Add Watermarks:
<?php
$imageResizerViewModel = $viewModels->require(ImageResizer::class);
?>
<img src="<?= $escaper->escapeUrl($imageResizerViewModel
->init('Magebit_StyleGuide::images/test2.jpg')
->watermark(
'Magebit_StyleGuide::images/test4.png', // Watermark image
'center', // Position: top-left, top-right, bottom-left, bottom-right, stretch, tile, center
'100, 100', // Size: "width, height"
20 // Opacity: 0-100
)->getUrl()) ?>"/>Configuration
Configuration Levels
The extension operates with multiple levels of configuration, where lower levels override higher ones:
1. Global Configurations
Set default values for all resized images (e.g., background color for all images).
File: app/design/frontend/Vendor/theme/etc/view.xml
<view xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Config/etc/view.xsd">
<vars module="Magebit_ImageResizer">
<!-- CONFIGURATIONS GOES THERE -->
<var name="background">255,255,255</var>
</vars>
</view>2. Image Type Configuration
Set values for groups of images when same configs must be applied to multiple images.
Allowed Configs:
- width, height, constrain, frame, aspect_ratio, transparency, background
File: app/design/frontend/Vendor/theme/etc/view.xml
<media>
<images module="Magebit_ImageResizer">
<image id="custom_image_1" type="image">
<width>30</width>
<height>30</height>
<constrain>true</constrain>
<frame>false</frame>
<aspect_ratio>true</aspect_ratio>
<transparency>false</transparency>
<background>0,0,0</background>
</image>
</images>
</media>Usage with Image ID:
<img src="<?= $imageResizerViewModel
->init('Magebit_StyleGuide::images/test.jpg', 'custom_image_1')
->getUrl(); ?>"/>3. Initialization Time Attributes
All configurations allowed at initialization time:
<img src="<?= $imageResizerViewModel
->init('Magebit_StyleGuide::images/test.jpg', 'custom_image_1', [
\Magebit\ImageResizer\Model\Config::VIEW_XML_ATTRIBUTE_WIDTH => 100,
\Magebit\ImageResizer\Model\Config::VIEW_XML_ATTRIBUTE_CONSTRAIN => false,
\Magebit\ImageResizer\Model\Config::VIEW_XML_VAR_ATTRIBUTE_ROTATE => 90
])
->getUrl(); ?>"/>4. ViewModel Method Configuration
The most preferred way to set configurations via viewModel methods.
Configuration Options
| Code | Type | Default | Description |
|---|---|---|---|
| type | string | image | Used to specify image type (image, thumbnail). Can be any text. Right now used to only set watermarks from catalog setting. |
| width | int | null | Used to specify width. If null, takes value from height |
| height | int | null | Used to specify height. If null, takes value from width |
| aspect_ratio | bool | true | Guarantee, that image picture width/height will not be distorted. |
| constrain | bool | true | Guarantee, that image picture will not be bigger, than it was. |
| frame | bool | null | Guarantee, that image will have dimensions, set in $width/$height. Not applicable, if keepAspectRatio(false). |
| object_fit_cover | bool | false | Works same as CSS object-fit property. Fit the size and crop the image. This property ignores keepFrame and keepAspectRatio. |
| background | array | [255, 255, 255] | Set color to fill image frame with. The keepTransparency(true) overrides this (if image has transparent color). |
| transparency | bool | true | Keep transparency for image if any. |
| rotate | int | null | Rotate image into specified angle |
| watermark | string | null | Watermark image path |
| watermark_position | string | null | Watermark position on image. Available values: top-left, top-right, bottom-left, bottom-right, stretch, tile, center |
| watermark_size | string | null | Watermark size on image. Format is "INTxINT" (example: "20x20") |
| watermark_opacity | int | null | Watermark opacity on image. |
| placeholder | string | null | Placeholder image path. |
| quality | int | null | Quality of the image. |
| webp_quality | int | 80 | WebP compression quality, tuned independently of quality. Resolves view.xml var, then admin config, then 80. Since 0.1.14. |
| catalog_quality | bool | true | Use catalog config quality. |
| is_catalog_watermark | bool | true | Use catalog config watermark. |
Admin Configuration
Image Resizer 0.1.14
These admin fields ship in Image Resizer 0.1.14 (bundled with Venta 1.6.4).
The extension adds three admin fields under Stores > Configuration > Advanced > System > Images Upload Configuration:
- Image Resizer WebP Quality (
system/upload_configuration/magebit_image_resizer_webp_quality) - WebP compression quality, 1 to 100, default 80. Store-scoped. Changing it regenerates cached WebP, since the value is part of the cache key. - Enable Image Resizer Logger - Turns on the extension's own logging.
- Enable Image Resizer Debug Logging - Depends on the logger. When off, resizer errors are condensed to a single-line summary; when on, full stack traces are logged.
Pre-generating responsive images (CLI)
Image Resizer 0.1.14
The pre-generation command ships in Image Resizer 0.1.14 (bundled with Venta 1.6.4).
Responsive WebP and retina variants are generated on demand the first time an image is requested. To warm them ahead of time, for example after a deployment, run:
bin/magento catalog:images:pregenerateThe command walks every registered image source and generates its variants, showing a progress bar per source. Add --async to publish the work to the message queue instead of processing inline, then run the consumer:
bin/magento catalog:images:pregenerate --async
bin/magento queue:consumers:start magebit.image_resizer.responsive_generate --single-thread --max-messages=1000This is separate from core catalog:images:resize. A module registers the images it wants pre-generated by implementing Magebit\ImageResizer\Api\ResponsiveImageSourceProviderInterface (getLabel() and getJobs()) and declaring it in di.xml.
WebP is encoded in a single pass directly from the resized image, rather than re-encoding a JPEG, which avoids a second round of lossy compression.
Caching
Cache Management
All resized images are located in pub/media/image_resizer/cache. Paths to resized images are stored in Magento cache.
Cache Behavior:
- If resized file doesn't exist or Magento cache is cleared, images will be resized again
- Cache can be cleared from Admin panel:
System > Cache Management > Pregenerated resized images files - Since 0.1.14 the clean action is gated by the module-owned ACL resource
Magebit_ImageResizer::clean_resized_images, so it can be granted to a dedicated admin role.
Cache Benefits:
- Improved performance through cached resized images
- Automatic regeneration when cache is cleared
- Centralized cache management through Magento admin