itiden/opixlig

Perfectly sized. Never pixelated.

Maintainers

Package info

github.com/itiden/laravel-opixlig

pkg:composer/itiden/opixlig

Statistics

Installs: 106

Dependents: 0

Suggesters: 0

Stars: 1

Open Issues: 0

v0.6.0 2025-07-02 07:59 UTC

README

Perfectly sized. Never pixelated.

Opixlig is a Laravel-friendly image component inspired by modern frameworks like Next.js — designed to make responsive, optimized images effortless. It automatically generates and serves the right image size and format for every device, keeping your pages fast, sharp, and beautifully adaptive. Write clean Blade, and let Opixlig handle the rest.

Latest Version on Packagist Total Downloads License

Features

  • 🖼️ Responsive images: Automatically generates and serves appropriately sized images for any device
  • 🚀 Performance optimized: Converts images to modern formats like WebP for faster loading
  • 📱 Adaptive srcsets: Creates optimized srcsets for both responsive and fixed-width images
  • 🔍 Placeholder support: Includes "blur" and "empty" placeholder options while images load
  • ⚙️ Highly configurable: Customize quality, widths, and more to fit your needs
  • 🎯 Presets: Define reusable image configurations for consistent sizing across your app
  • 🛠️ Simple API: Clean Blade component syntax that feels natural in your Laravel views

Installation

You can install the package via composer:

composer require itiden/opixlig

Publishing the config

php artisan vendor:publish --tag="itiden-opixlig-config"

Configuration

After publishing the config file, you can customize the following settings in config/opixlig.php:

return [
    // Where generated images are stored in your storage directory
    'storage_folder' => 'app/.images',

    // Public URL path to access the images
    'public_folder' => 'images',

    // Image manipulation driver ('imagick' or 'gd')
    'driver' => 'imagick',

    // Defaults for image output
    'defaults' => [
        // Default widths for responsive images
        'widths' => [384, 640, 828, 1200, 2048, 3840],

        // Default placeholder type ('empty' or 'blur')
        'placeholder' => 'empty',

        // Default image quality (1-100)
        'quality' => 75,

        // Default image format ('webp', 'avif', 'png', 'jpg', 'pjpg', 'gif', 'heic')
        'format' => 'webp',
    ],

    // Reusable image presets
    'presets' => [
        // 'thumbnail' => [
        //     'width' => 150,
        //     'height' => 150,
        //     'quality' => 60,
        //     'fit' => 'crop-center',
        //     'placeholder' => 'blur',
        // ],
    ],
];

Usage

Basic Example

Use the Blade component in your views:

<x-opixlig::image
    src="public/images/hero.jpg"
    width="800"
    height="600"
    alt="Hero image"
/>

Note: width and height must always be provided together. Supplying only one will throw an InvalidArgumentException. Omitting both is valid and renders a plain <img> with no srcset.

Responsive Images with Custom Sizes

<x-opixlig::image
    src="public/images/hero.jpg"
    sizes="(max-width: 768px) 100vw, 50vw"
    width="1200"
    height="800"
    alt="Responsive hero image"
/>

Using Blur Placeholder

<x-opixlig::image
    src="public/images/hero.jpg"
    width="800"
    height="600"
    placeholder="blur"
    alt="Hero image with blur placeholder"
/>

Custom Quality

<x-opixlig::image
    src="public/images/hero.jpg"
    width="800"
    height="600"
    quality="90"
    alt="High quality hero image"
/>

Cropped Image

<x-opixlig::image
    src="public/images/hero.jpg"
    width="800"
    height="600"
    fit="crop-center"
    alt="Center-cropped hero image"
/>

Additional Manipulations

<x-opixlig::image
    src="public/images/hero.jpg"
    width="800"
    height="600"
    :manipulations="['blur' => 10, 'bri' => 20]"
    alt="Blurred and brightened hero image"
/>

Presets

Define reusable image configurations in your config/opixlig.php:

'presets' => [
    'avatar' => [
        'width' => 64,
        'height' => 64,
        'quality' => 70,
        'fit' => 'crop-center',
        'placeholder' => 'blur',
    ],
    'hero' => [
        'width' => 1200,
        'height' => 630,
        'format' => 'avif',
        'quality' => 85,
    ],
    'og-image' => [
        'w' => 1200,
        'h' => 630,
        'fm' => 'jpg',
        'q' => 80,
    ],
],

Presets support both friendly names (width, height, format, quality) and Glide shorthand keys (w, h, fm, q). You can also include any Glide manipulation like blur, filt, or sharp, as well as placeholder and widths.

Use a preset via the preset prop:

<x-opixlig::image src="public/images/profile.jpg" preset="avatar" alt="User avatar" />

Inline props override preset values, so you can use a preset as a base and tweak individual settings:

<x-opixlig::image
    src="public/images/profile.jpg"
    preset="avatar"
    width="128"
    height="128"
    quality="90"
    alt="Large avatar"
/>

Presets can also define custom widths for responsive srcsets:

{{-- Config: 'banner' => ['w' => 1200, 'h' => 400, 'widths' => [400, 800, 1200]] --}}
<x-opixlig::image src="public/images/banner.jpg" preset="banner" sizes="100vw" alt="Banner" />

Using the Helper Function

You can also use the img() helper function directly:

$imageUrl = img('public/images/hero.jpg', 800, 600, ['fm' => 'webp', 'q' => 80])->url(['w' => 800]);

The helper also supports presets:

$avatarUrl = img('public/images/profile.jpg', preset: 'avatar')->url(['w' => 64]);

Advanced Usage

Available Props

Prop Type Default Description
src string '' Path to the source image (including disk name e.g., 'public/images/file.jpg')
preset string '' Name of a preset defined in config('opixlig.presets'). Inline props override preset values.
sizes string '' Media query sizes attribute for responsive images
width number '' Width of the image. Must be provided together with height — supplying only one throws an error.
height number '' Height of the image. Must be provided together with width — supplying only one throws an error.
loading string 'lazy' Image loading strategy ('lazy', 'eager', 'auto')
decoding string 'async' Image decoding strategy ('async', 'sync', 'auto')
quality number config('opixlig.defaults.quality') Image quality (1-100)
placeholder string config('opixlig.defaults.placeholder') Placeholder type ('empty' or 'blur')
format string config('opixlig.defaults.format') Image format ('jpg', 'pjpg', 'png', 'gif', 'webp', 'avif', 'heic'*). *heic only supported with Imagick driver
fit string '' How the image is fitted to its target dimensions. Values: 'contain', 'max', 'fill', 'fill-max', 'stretch', 'crop'. For crop positioning, use e.g. 'crop-center', 'crop-top', or Statamic focal points like 'crop-44-13-1'
manipulations array [] Additional Glide manipulations as key-value pairs

Image Manipulations

The fit prop covers the most common resize/crop use cases (including Statamic focal point crops like fit="crop-44-13-1"), but you can pass any Glide manipulation parameter via the manipulations prop:

<x-opixlig::image
    src="public/images/hero.jpg"
    width="800"
    height="600"
    fit="crop-center"
    :manipulations="['sharp' => 50, 'filt' => 'greyscale']"
    alt="Cropped greyscale hero"
/>

All supported Glide manipulations:

Parameter Key Description
Width w Width in pixels (set via width prop)
Height h Height in pixels (set via height prop)
Fit fit Resize method (set via fit prop)
Crop crop Pixel-based crop: 'width,height,x,y' (via manipulations)
Quality q Image quality, 0-100 (set via quality prop)
Format fm Output format (set via format prop)
Blur blur Blur amount (0-100)
Sharpen sharp Sharpen amount (0-100)
Brightness bri Brightness adjustment (-100 to 100)
Contrast con Contrast adjustment (-100 to 100)
Gamma gam Gamma adjustment (0.1 to 9.99)
Pixelate pixel Pixelate amount (0-1000)
Filter filt Filter ('greyscale', 'sepia')
Flip flip Flip ('h', 'v', 'both')
Orientation or Rotation ('auto', '90', '180', '270')
Background bg Background color (hex, e.g. 'fff')
Border border Border ('width,color,method')

How It Works

  1. The component generates optimized images on demand
  2. Images are processed using the configured driver (Imagick or GD)
  3. Processed images are stored in the configured cache directory
  4. Subsequent requests for the same image with the same parameters are served directly from cache without hitting laravel
  5. The package automatically generates appropriate srcsets for responsive designs

Contributing

Please see CONTRIBUTING.md for details.

License

The MIT License (MIT). Please see License File for more information.