Skip to content

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/media and module folders
  • 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:

bash
composer require magebitcom/magento2-image-resizer

Post-Installation Steps:

bash
bin/magento setup:upgrade

Usage

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:

  1. Pub Media Path: style-guide/test1.jpg - located in pub/media/style-guide/test1.jpg
  2. Module Asset: Magebit_StyleGuide::images/test1.jpg - located in module's web directory

Basic Resizing Examples:

Image from pub/media directory:

php
<?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
<?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
<?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
<?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 model
  • string $imageAttribute - Image attribute (default: image)
  • string $imageId - Image ID
  • array $attributes - Additional attributes

Responsive Picture Generation

Generate responsive picture tags with sources for Desktop and Mobile using getResponsivePicture:

php
<?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 _mobile suffix 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
<?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
<?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 $tabletUrl and ?array $tabletSize add a tablet <source> between mobile and desktop. When only a size or a _tablet image id is given, the desktop URL is reused.
  • A matching _tablet image id in view.xml is resolved automatically, in the same way _mobile already is.
  • int $mobileMaxWidth (default 767) and int $tabletMaxWidth (default 1024) set the breakpoints, so they are no longer fixed.
  • int $mobileMinWidth and int $tabletMinWidth (default 0) make a tier use a ranged min-width/max-width media 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):

php
$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
<?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
<?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
<?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
<?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
<?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
<?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
<?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
<?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
<?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

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

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:

php
<img src="<?= $imageResizerViewModel
              ->init('Magebit_StyleGuide::images/test.jpg', 'custom_image_1')
              ->getUrl(); ?>"/>

3. Initialization Time Attributes

All configurations allowed at initialization time:

php
<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

CodeTypeDefaultDescription
typestringimageUsed to specify image type (image, thumbnail). Can be any text. Right now used to only set watermarks from catalog setting.
widthintnullUsed to specify width. If null, takes value from height
heightintnullUsed to specify height. If null, takes value from width
aspect_ratiobooltrueGuarantee, that image picture width/height will not be distorted.
constrainbooltrueGuarantee, that image picture will not be bigger, than it was.
frameboolnullGuarantee, that image will have dimensions, set in $width/$height. Not applicable, if keepAspectRatio(false).
object_fit_coverboolfalseWorks same as CSS object-fit property. Fit the size and crop the image. This property ignores keepFrame and keepAspectRatio.
backgroundarray[255, 255, 255]Set color to fill image frame with. The keepTransparency(true) overrides this (if image has transparent color).
transparencybooltrueKeep transparency for image if any.
rotateintnullRotate image into specified angle
watermarkstringnullWatermark image path
watermark_positionstringnullWatermark position on image. Available values: top-left, top-right, bottom-left, bottom-right, stretch, tile, center
watermark_sizestringnullWatermark size on image. Format is "INTxINT" (example: "20x20")
watermark_opacityintnullWatermark opacity on image.
placeholderstringnullPlaceholder image path.
qualityintnullQuality of the image.
webp_qualityint80WebP compression quality, tuned independently of quality. Resolves view.xml var, then admin config, then 80. Since 0.1.14.
catalog_qualitybooltrueUse catalog config quality.
is_catalog_watermarkbooltrueUse 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:

bash
bin/magento catalog:images:pregenerate

The 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:

bash
bin/magento catalog:images:pregenerate --async
bin/magento queue:consumers:start magebit.image_resizer.responsive_generate --single-thread --max-messages=1000

This 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