PHPackages                             pjedesigns/filament-image-editor - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Search &amp; Filtering](/categories/search)
4. /
5. pjedesigns/filament-image-editor

ActiveLibrary[Search &amp; Filtering](/categories/search)

pjedesigns/filament-image-editor
================================

A powerful, client-side image editor for Laravel Filament applications with crop, filter, and annotation tools

v1.0.1(1mo ago)06MITJavaScriptPHP ^8.2CI passing

Since Jan 23Pushed 1mo agoCompare

[ Source](https://github.com/pjedesigns/filament-image-editor)[ Packagist](https://packagist.org/packages/pjedesigns/filament-image-editor)[ Docs](https://github.com/pjedesigns/filament-image-editor)[ RSS](/packages/pjedesigns-filament-image-editor/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (1)Dependencies (20)Versions (3)Used By (0)

Filament Image Editor
=====================

[](#filament-image-editor)

A powerful, client-side image editor plugin for Laravel Filament applications with crop, filter, and annotation tools.

Features
--------

[](#features)

- 🖼️ **Crop &amp; Transform** - Crop with aspect ratio presets, rotate, and flip images
- 🎨 **Filters &amp; Adjustments** - Apply preset filters and adjust brightness, contrast, saturation
- ✏️ **Draw &amp; Annotate** - Freehand drawing, shapes, arrows, and text annotations
- ⏪ **Undo/Redo** - Full history support with keyboard shortcuts
- 📱 **Responsive** - Works on desktop and tablet devices
- 🌙 **Dark Mode** - Full dark mode support matching Filament's theme
- 💾 **Flexible Storage** - Works with Laravel Storage or Spatie Media Library

Requirements
------------

[](#requirements)

- PHP 8.2+
- Laravel 12+
- Filament v4/v5
- Livewire v3/v4

Installation
------------

[](#installation)

Install the package via Composer:

```
composer require pjedesigns/filament-image-editor
```

Publish the config file (optional):

```
php artisan vendor:publish --tag="filament-image-editor-config"
```

Basic Usage
-----------

[](#basic-usage)

Use the `ImageEditor` field in your Filament form:

```
use Pjedesigns\FilamentImageEditor\Forms\Components\ImageEditor;

public static function form(Form $form): Form
{
    return $form->schema([
        ImageEditor::make('avatar')
            ->label('Profile Picture')
            ->required(),
    ]);
}
```

Configuration
-------------

[](#configuration)

### Storage Options

[](#storage-options)

Configure how images are stored:

```
ImageEditor::make('photo')
    ->disk('public')
    ->directory('photos')
    ->visibility('public')
    ->shouldPreserveFilenames()  // Keep original filename (slugified)
```

#### Filename Options

[](#filename-options)

By default, images are saved with a UUID filename (e.g., `550e8400-e29b-41d4-a716-446655440000.jpg`). Use `shouldPreserveFilenames()` to keep the original filename:

```
ImageEditor::make('photo')
    ->shouldPreserveFilenames()  // "My Vacation Photo.PNG" → "my-vacation-photo.jpg"
```

The original filename is slugified (lowercase, special characters replaced with hyphens) and the extension is set based on the output format.

### With Spatie Media Library

[](#with-spatie-media-library)

> **Important:** This component only supports single-file collections. When defining your Spatie Media Library collection on the model, you must use `->singleFile()`:
>
> ```
> // In your Model
> public function registerMediaCollections(): void
> {
>     $this->addMediaCollection('avatar')
>         ->singleFile();  // Required for ImageEditor
> }
> ```

```
ImageEditor::make('photo')
    ->collection('photos')
    ->conversion('thumb')
    ->responsiveImages()
    ->customProperties(['source' => 'editor'])
```

#### Dynamic custom properties (using the current record)

[](#dynamic-custom-properties-using-the-current-record)

You can pass a Closure to `customProperties()` to generate properties based on the current record:

```
use Illuminate\Database\Eloquent\Model;

ImageEditor::make('photo')
    ->collection('photos')
    ->customProperties(fn (?Model $record) => [
        'custom_property'  => $record?->custom_property ?: (string) 'default',
        'source'       => 'editor',
    ]);
```

### Editor Behavior

[](#editor-behavior)

```
ImageEditor::make('image')
    ->openOnSelect(true)    // Open editor immediately when file selected (default)
    ->openOnSelect(false)   // Skip editor - upload image directly, edit later via "Edit" button
    ->modalSize('6xl')      // Modal size (sm, md, lg, xl, 2xl, 3xl, 4xl, 5xl, 6xl, 7xl, full)
    ->tools(['crop', 'filter', 'draw'])  // Available tools
    ->previewMaxHeight(400) // Maximum height for image preview in pixels (default: 400)
```

The `previewMaxHeight` option controls the maximum height of the image preview on the form. Images smaller than this height will display at their natural size without stretching, while larger images will be constrained to the max height. This prevents pixelation when displaying smaller conversion images.

When `openOnSelect(false)` is set:

- Images are uploaded directly without opening the editor
- The thumbnail appears with an "Edit" button overlay
- Users can optionally click "Edit" to make changes later

### Crop Options

[](#crop-options)

```
ImageEditor::make('image')
    ->cropAspectRatios([
        'free' => null,
        '1:1' => 1,
        '16:9' => 16/9,
        'cinematic' => 2.35,
    ])
    ->defaultAspectRatio('16:9')
    ->cropMinSize(width: 100, height: 100)
    ->cropMaxSize(width: 4000, height: 4000)
    ->enableRotation(true)
    ->enableFlip(true)
```

### Filter Options

[](#filter-options)

```
ImageEditor::make('image')
    ->filterPresets([
        'original', 'grayscale', 'sepia', 'vintage',
        'warm', 'cool', 'dramatic', 'fade', 'vivid',
    ])
    ->adjustments(['brightness', 'contrast', 'saturation'])
    ->disableFilters()      // Only show adjustments
    ->disableAdjustments()  // Only show filter presets
```

### Drawing Options

[](#drawing-options)

```
ImageEditor::make('image')
    ->drawingTools(['select', 'freehand', 'eraser', 'line', 'arrow', 'rectangle', 'ellipse', 'text'])
    ->defaultStrokeColor('#FF0000')
    ->defaultStrokeWidth(4)
    ->defaultFillColor('transparent')
    ->colorPalette([
        '#FFFFFF', '#000000', '#FF0000', '#00FF00', '#0000FF',
    ])
    ->fonts(['Arial', 'Helvetica', 'Georgia'])
    ->disableDrawing()  // Remove drawing tool entirely
```

### Output Options

[](#output-options)

```
ImageEditor::make('image')
    ->outputFormat('webp')      // jpeg, png, webp
    ->outputQuality(0.85)       // 0.0 to 1.0
    ->maxOutputSize(width: 2000, height: 2000)
```

### Validation

[](#validation)

```
ImageEditor::make('image')
    ->acceptedFileTypes(['image/jpeg', 'image/png', 'image/webp'])
    ->maxFileSize(5 * 1024)     // 5MB in KB
    ->minDimensions(width: 800, height: 600)  // Warning threshold
```

### History &amp; Shortcuts

[](#history--shortcuts)

```
ImageEditor::make('image')
    ->historyLimit(50)
    ->enableKeyboardShortcuts(true)
```

Keyboard Shortcuts
------------------

[](#keyboard-shortcuts)

When the editor is open:

ShortcutAction`Ctrl/Cmd + Z`Undo`Ctrl/Cmd + Y`Redo`Ctrl/Cmd + Shift + Z`Redo`Delete` / `Backspace`Delete selected shape`Ctrl/Cmd + D`Duplicate selected`Escape`Deselect / CancelZoom &amp; Pan Controls
-----------------------

[](#zoom--pan-controls)

The editor provides several ways to zoom and pan around the image:

### Zooming

[](#zooming)

- **Mouse wheel** - Scroll up/down to zoom in/out (zooms to cursor position)
- **Zoom dropdown** - Select preset zoom levels (Fit, 50%, 100%, 200%)
- **Zoom buttons** - Use +/- buttons in the bottom toolbar

### Panning (when zoomed in)

[](#panning-when-zoomed-in)

- **Alt + Click &amp; Drag** - Hold Alt key and drag to pan the canvas
- **Middle Mouse Button** - Click and drag with middle mouse button to pan

The "Fit" option in the zoom dropdown resets the view to fit the entire image in the viewport.

Standalone Livewire Component
-----------------------------

[](#standalone-livewire-component)

You can also use the editor as a standalone Livewire component:

```

```

JavaScript API
--------------

[](#javascript-api)

For programmatic usage outside of Livewire:

```
window.FilamentImageEditor.open({
    source: '/path/to/image.jpg',
    tools: ['crop', 'filter', 'draw'],
    onApply: (file) => {
        console.log('Edited image:', file);
    },
    onCancel: () => {
        console.log('User cancelled');
    }
});
```

Configuration File
------------------

[](#configuration-file)

After publishing the config, you can set defaults in `config/filament-image-editor.php`:

```
return [
    'storage' => [
        'disk' => 'public',
        'directory' => 'images',
        'visibility' => 'public',
    ],

    'output' => [
        'format' => 'jpeg',
        'quality' => 0.92,
    ],

    'ui' => [
        'preview_max_height' => 400,  // Max height for image preview in pixels
    ],

    'tools' => ['crop', 'filter', 'draw'],

    'crop' => [
        'aspect_ratios' => [
            'free' => null,
            '1:1' => 1,
            '4:3' => 4/3,
            '16:9' => 16/9,
        ],
        'enable_rotation' => true,
        'enable_flip' => true,
    ],

    // ... more options
];
```

Testing
-------

[](#testing)

### Running Tests in Your Application

[](#running-tests-in-your-application)

For full test coverage including Livewire integration tests, publish the tests to your Laravel application:

```
# Publish tests to your application
php artisan vendor:publish --tag=filament-image-editor-tests

# Run the tests
php artisan test tests/Feature/FilamentImageEditor
```

This publishes tests to `tests/Feature/FilamentImageEditor/` and runs all 44 tests including:

- **Storage Tests** - Saving images to disk, directory configuration, file extensions
- **Spatie Media Library Tests** - Collection, conversion, responsive images configuration
- **Field Configuration Tests** - All form field options and closures

### Package Development

[](#package-development)

When developing the package itself:

```
# Install dependencies
composer install

# Run standalone tests (skips Livewire integration tests)
composer test

# Or run via the parent Laravel application for full coverage
cd /path/to/laravel-app
php artisan test packages/pjedesigns/filament-image-editor/tests
```

> **Note:** Livewire integration tests require a full Laravel application context and will be skipped when running standalone via `composer test`. Use the publish method above or run via a Laravel application for complete test coverage.

Changelog
---------

[](#changelog)

Please see [CHANGELOG](CHANGELOG.md) for more information on what has changed recently.

Contributing
------------

[](#contributing)

Please see [CONTRIBUTING](CONTRIBUTING.md) for details.

Security
--------

[](#security)

If you discover any security-related issues, please email  instead of using the issue tracker.

Credits
-------

[](#credits)

- [Paul Egan](https://github.com/pjedesigns)
- [All Contributors](../../contributors)

License
-------

[](#license)

The MIT License (MIT). Please see [License File](LICENSE.md) for more information.

###  Health Score

40

—

FairBetter than 88% of packages

Maintenance91

Actively maintained with recent releases

Popularity6

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity48

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~68 days

Total

2

Last Release

41d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/2a15191491946f1c868f8a6df1065b533febfe66d6a31e226c2362567577fbb0?d=identicon)[pjedesigns](/maintainers/pjedesigns)

---

Top Contributors

[![pjedesigns](https://avatars.githubusercontent.com/u/55060365?v=4)](https://github.com/pjedesigns "pjedesigns (16 commits)")

---

Tags

laravelfiltercropannotationimage editorfilamentfilamentphppjedesignsfabric-js

###  Code Quality

TestsPest

Code StyleLaravel Pint

### Embed Badge

![Health badge](/badges/pjedesigns-filament-image-editor/health.svg)

```
[![Health](https://phpackages.com/badges/pjedesigns-filament-image-editor/health.svg)](https://phpackages.com/packages/pjedesigns-filament-image-editor)
```

###  Alternatives

[webbingbrasil/filament-advancedfilter

Advanced filter component for filament admin.

146132.1k](/packages/webbingbrasil-filament-advancedfilter)[dotswan/filament-map-picker

Easily pick and retrieve geo-coordinates using a map-based interface in your Filament applications.

124139.3k2](/packages/dotswan-filament-map-picker)[relaticle/custom-fields

User Defined Custom Fields for Laravel Filament

15828.6k](/packages/relaticle-custom-fields)[jibaymcs/filament-tour

Bring the power of DriverJs to your Filament panels and start a tour !

12247.8k](/packages/jibaymcs-filament-tour)[kainiklas/filament-scout

Filament Plugin to integrate Scout into Global Search and Table Search.

3573.3k](/packages/kainiklas-filament-scout)[guava/filament-modal-relation-managers

Allows you to embed relation managers inside filament modals.

7565.0k4](/packages/guava-filament-modal-relation-managers)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
