tito10047/progressive-image-bundle

High-performance progressive image loading bundle for Symfony with Blurhash placeholders, zero CLS, and smart responsive strategies.

Installs: 133

Dependents: 0

Suggesters: 0

Security: 0

Stars: 13

Watchers: 1

Forks: 0

Open Issues: 1

Type:symfony-bundle

pkg:composer/tito10047/progressive-image-bundle

1.1.2 2026-01-21 16:49 UTC

This package is auto-updated.

Last update: 2026-01-21 16:53:02 UTC


README

Build Status PHP-CS-Fixer PHPStan Latest Stable Version License PHP Version Symfony Version Symfony Style Coverage Status

High-performance, Zero-config, Fully Responsive Images for Symfony.

This bundle handles everything you need for modern image management. From fully responsive images with Tailwind-like selectors, to blur placeholders, to * automatic generation of all required sizes* on local or network storage.

✨ Key Features

  • πŸš€ Zero Configuration: Install and use. Most features work out of the box.
  • 🎨 Blur & Error Placeholders: Users see a beautiful Blurhash placeholder while loading. If an image is not found, the bundle automatically displays a stylish error placeholder.
  • πŸ–ΌοΈ Responsive via <picture>: Uses the modern <picture> element with multiple <source> tags for optimal browser selection and performance.
  • πŸ“± Tailwind-like Selectors: Define responsiveness naturally directly in your template using familiar breakpoints.
  • πŸ–ΌοΈ Retina Support: Automatically generates 1x, 2x (and more) versions for high-density displays.
  • βš™οΈ Automatic Generation: The bundle automatically generates all necessary image sizes on disk (local or network), saving time and resources.
  • 🎯 Zero CLS (Cumulative Layout Shift): Automatically reserves space for the image, preventing content jumping during load.
  • ⚑ Smart Preload: Automatically injects <link rel="preload"> for critical images (hero images), significantly improving LCP scores.

🎨 Usage

Simply use the Twig component. The bundle takes care of everything β€” it automatically calculates the required image dimensions for each breakpoint, resizes the original, and generates all necessary variants on the fly.

{# Basic usage - everything is automatic #}
<twig:pgi:Image src="images/hero.jpg" alt="Beautiful landscape" />

{# With Tailwind-like selectors for perfect responsiveness #}
<twig:pgi:Image 
    src="images/hero.jpg" 
    sizes="sm:12 md:6@landscape lg:4@square"
    alt="Responsive image" 
/>

πŸ“± Selector Examples (Breakpoint Assignment)

The bundle supports flexible size assignment based on breakpoints you know from Tailwind or Bootstrap. For each selector, it automatically calculates the final pixel dimensions based on the container width defined by your CSS framework (Bootstrap or Tailwind) and generates the corresponding image.

Selector Meaning Resulting behavior
6 6 grid columns on all breakpoints Width: 50% of container, original aspect ratio
md:6 6 grid columns from md breakpoint From md up: 50% of container, below md: full width
lg:4@landscape 4 columns from lg with 16:9 aspect ratio From lg up: 33.3% of container, cropped to 16:9 ratio
xs:12@square 12 columns on xs with 1:1 aspect ratio Full width container, cropped to 1:1 square
xxl:[430x370] Explicit dimensions for a specific breakpoint Exact size 430x370px on xxl and larger
xl:[100%]@landscape 100% container width with landscape aspect ratio Full width container, cropped to 16:9 ratio
lg:4@square|circle 4 columns on lg with custom modifier Passes circle to processing pipeline (e.g. crop)

What is a "container"? The bundle automatically detects your CSS framework (Bootstrap or Tailwind) and extracts the exact container widths for each breakpoint from its configuration. It then uses these values to calculate the precise pixel dimensions for your images.

πŸš€ Advanced Features

Point of Interest (PoI) Cropping

Define a focal point (e.g., 75x25) so the most important object remains in frame regardless of the crop.

Smart Upscaling Protection

The bundle never generates an image larger than the original. If you need 1200px but the original is only 1000px, the bundle uses the original and prevents blurring.

Stream-based Metadata

To retrieve dimensions and Blurhash, the bundle doesn't load the entire image into RAM (no 20MB files in memory). It uses PHP streams to read only the necessary header bytes.

Custom Modifiers & Filters

Extend the selector logic with your own modifiers (e.g., lg:4|circle). You can implement custom logic for filters like circle, grayscale, or sepia and even prioritize them to override default behavior.

πŸ“¦ Installation

composer require tito10047/progressive-image-bundle

βš™οΈ Optional Configuration

# config/packages/progressive_image.yaml
progressive_image:
    responsive_strategy:
        grid:
            framework: tailwind # or bootstrap
        ratios:
            landscape: "16/9"
            portrait: "3/4"
            square: "1/1"
    image_cache_enabled: true
    retina:
        enabled: true
        multipliers: [1, 2]

πŸ“„ License

MIT License. See LICENSE for more information.

πŸ“š Documentation

For detailed guides, configuration, and advanced features, check out our full documentation:

πŸ“œ Changelog

All notable changes to this project are documented in CHANGELOG.md.