itiden / opixlig
Perfectly sized. Never pixelated.
Requires
- php: ^8.1.0
- illuminate/bus: ^10.2|^11.0|^12.0
- illuminate/events: ^10.2|^11.0|^12.0
- illuminate/http: ^10.2|^11.0|^12.0
- illuminate/support: ^10.2|^11.0|^12.0
- league/glide: ^2.0
Requires (Dev)
- laravel/pint: ^1.18.1
- pestphp/pest: ^3.5.1
- pestphp/pest-plugin-type-coverage: ^3.1
- phpstan/phpstan: ^1.12.7
- rector/rector: ^1.2.8
- symfony/var-dumper: ^7.1.6
This package is auto-updated.
Last update: 2026-03-09 14:52:17 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.
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:
widthandheightmust always be provided together. Supplying only one will throw anInvalidArgumentException. 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
- The component generates optimized images on demand
- Images are processed using the configured driver (Imagick or GD)
- Processed images are stored in the configured cache directory
- Subsequent requests for the same image with the same parameters are served directly from cache without hitting laravel
- 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.