Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Image Laravel Package

illuminate/image

Illuminate Image is a lightweight Laravel package offering a clean, fluent API for loading, resizing, cropping, converting, and caching images. It supports GD and Imagick drivers and integrates smoothly with Blade views, storage disks, and Laravel's filesystem. Simple image handling for Laravel apps...

View on GitHub
Deep Wiki
Context7

Getting Started

illuminate/image is a small, community-maintained package (35 stars, MIT) from the illuminate GitHub org — not an official first-party Laravel package. Treat it as a thin, opinionated convenience layer rather than a framework component.

Minimal steps:

composer require illuminate/image
  1. Read composer.json first. Confirm the illuminate/support and illuminate/filesystem version constraints match your Laravel version, and note whether it pulls intervention/image, gd, or imagick as the underlying driver. This single file tells you more than the README about whether it will fit your app.
  2. Check for a service provider. If the package ships one, Laravel auto-discovers it. If not, you're likely using it statically or instantiating a class directly — look at src/ for a facade or a Image::make()-style entry point.
  3. Publish config if present (php artisan vendor:publish --tag=image-config) to set the default driver, quality, and disk. If there's no config file, hardcode as little as possible in your own config/images.php.
  4. Verify the driver at runtime before building on it: check that gd or imagick is actually installed in your container/CI, not just locally.

First use case: a thumbnail pipeline behind an upload form.

// app/Http/Controllers/AvatarController.php
public function store(StoreAvatarRequest $request)
{
    $path = $request->file('avatar')->store('avatars/original', 'public');

    Image::make(Storage::disk('public')->path($path))
        ->fit(256, 256)
        ->save(Storage::disk('public')->path("avatars/thumb/{$basename}.jpg"));

    return back()->with('status', 'Uploaded');
}

Start there — one controller, one disk, one size — then generalize once you know how the package behaves with your files.

Implementation Patterns

Wrap it in a dedicated service. Because the package is small and could be abandoned or swapped, isolate calls behind your own class. If you later move to Intervention Image, Spatie's image-optimizer, or Glide, you change one file.

// app/Services/ImageProcessor.php
class ImageProcessor
{
    public function thumbnail(string $absolutePath, int $size): string
    {
        $out = $this->thumbPath($absolutePath, $size);
        Image::make($absolutePath)->fit($size, $size)->save($out);

        return $out;
    }
}

Use it in queued jobs, not controllers, for anything >1 image. Image decoding is CPU- and memory-bound; a 12MP JPEG can cost 50–100MB of RAM. Dispatch a job after the upload is safely stored, and keep the original as the source of truth.

class GenerateThumbnails implements ShouldQueue
{
    public function __construct(public string $path) {}

    public function handle(ImageProcessor $processor): void
    {
        foreach ([128, 256, 512] as $size) {
            $processor->thumbnail(Storage::disk('public')->path($this->path), $size);
        }
    }
}

Prefer absolute paths over URLs. Almost every image package wants a filesystem path, not a public URL. Use Storage::disk('x')->path($relative) and Storage::disk('x')->put() — never asset() — when persisting.

Expose variants via a DB column, not string building in Blade. Store the base path once and derive variants in a single accessor/helper so 128, 256, 512 stay consistent between the job and the view. This prevents the classic "thumbnail exists in dev but not prod because the size constant drifted" bug.

Test with Storage::fake(). Since the package writes to real files, fakes keep tests fast. For the image logic itself, commit a couple of tiny fixture files (a 2×2 PNG, an EXIF-rotated JPEG) rather than generating images in the test.

Integration tip — form requests do validation, not the package. MIME checks (image, mimes:jpg,png,webp), file size, and dimension limits belong in StoreAvatarRequest. Assume the package does not sandbox inputs.

Gotchas and Tips

  • It's a 35-star package. Pin the version in composer.json, read the source before relying on it, and keep your abstraction layer thin. There is no LTS guarantee, no security team, no deprecation policy. Budget for replacement.
  • Driver mismatch between local and production. gd and imagick handle transparency, color profiles, and EXIF orientation differently. Confirm the same extension is installed in Docker/CI/Forge. A common symptom is WebP uploads failing only in production.
  • EXIF orientation. Phone photos carry an orientation flag; naive resize leaves them sideways. Check whether the package calls ->orientate() / ->autoOrient() automatically — many thin wrappers don't. If not, add it explicitly.
  • Memory limits. Large images can Allowed memory size exhausted. Raise memory_limit in the queue worker, or check dimensions (getimagesize) and reject oversized uploads before decoding.
  • Config caching. If the package has a config file and uses env() inside it, php artisan config:cache will null those values in production. Move env reads into config/*.php of your own if needed.
  • SVG handling. SVG is XML, not raster. If the package accepts image/svg+xml, you have an XSS/SSRF surface. Reject SVG at validation unless you have a sanitizer (e.g. enshrined/svg-sanitize).
  • Decompression bombs. A 100KB PNG can decode to gigabytes. Enforce pixel-count limits from getimagesize(), not just file size.
  • Quality and format defaults are silent. Default JPEG quality (often 75–90) and output format may differ from the input (a PNG with alpha might become a black-backed JPEG). Always pass quality explicitly and preserve format where transparency matters.
  • Extension points are limited. With a small package, expect no driver abstraction. The realistic extension points are: (1) your own ImageProcessor wrapper, (2) Laravel macros if it exposes a fluent class, (3) replacing it. Don't invest in patching it.
  • Debugging tip: when output looks wrong, log the actual command/driver path. Add a one-off dd(get_class(Image::make($path)), getimagesize($path)) to confirm the driver and source dimensions before assuming the package is at fault.
  • Filesystem permissions in the queue context. Workers often run as a different user than the web server. If thumbnails write as www-data but the queue is forge, you'll get Permission denied on .save(). Set the disk root permissions once and test the queue path in staging.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
vento/laravel-airbrake
wfeller/laravel-batch
maco-studios/mage-os-installer
busarm/armie
siberfx/laravel-logger
kfteam1991/dcat-admin
dashed/dashed-laposta
dashed/dashed-ecommerce-montaportal
dashed/dashed-ecommerce-etsy
neohq/string-blade-compiler
log1x/acf-composer
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core
nodisrupt/laravel-agent
sierratecnologia/media-manager