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

Application Utils Image Laravel Package

mistralys/application-utils-image

Image utilities for PHP applications: helpers for handling, processing, and converting images, with a clean API for common tasks like resizing, format detection, and file operations. Integrates easily into existing projects.

View on GitHub
Deep Wiki
Context7

Getting Started

This package is the image-handling companion to the broader application-utils collection. Install it alongside Laravel like any other library:

composer require mistralys/application-utils-image

Before writing code, open vendor/mistralys/application-utils-image/composer.json and read the autoload block — the collection uses a few different namespace conventions across packages (e.g. AppUtils\...), and the image classes live under an Image-scoped namespace. Confirm the exact FQCNs there rather than guessing, then skim src/ for the base ImageFile/ImageHelper classes.

The first thing to look at is ImageHelper, which is the static entry point for loading and inspecting images. Start with the smallest useful use case: take an uploaded or on-disk file, wrap it in a typed file object, and read its dimensions/type without manipulating it.

use AppUtils\ImageHelper; // verify namespace from composer.json

$image = ImageHelper::createFromFile('/path/to/uploads/photo.jpg');

echo $image->getWidth();   // e.g. 1920
echo $image->getHeight();  // e.g. 1080

Then compare it to a raster file class to see what the abstraction buys you:

use AppUtils\ImageFile\JPGFile; // verify namespace

if ($image instanceof JPGFile) {
    // JPEG-specific behaviour (EXIF, quality, progressive encoding)
}

For 1.2.0 specifically, the new GIFFile, JPGFile, PNGFile and SVGFile classes mean you should now prefer the typed subclasses over raw GD resources or getimagesize() arrays — they carry format identity and expose format-aware behaviour through a common interface.

Implementation Patterns

Load once, branch on type. Wrap every image that enters your app (upload, seeded fixture, remote download) through ImageHelper, then dispatch on instanceof or a getType()-style accessor rather than on file extension. This keeps one code path and makes the SVGFile case explicit:

$image = ImageHelper::createFromFile($absolutePath);

if ($image instanceof SVGFile) {
    // Vector: don't raster-resize. Store as-is, render via <img>, or
    // rasterise separately if you need a bitmap thumbnail.
} else {
    // Raster: safe to resize/crop/re-encode.
}

Custom upload validation. Laravel's image validation rule covers the common raster formats; the new SVGFile class lets you be deliberate about SVGs instead of accidentally allowing or blocking them. Combine a rule-level extension/mime check with a post-validation ImageHelper load, so a file that passes the rule but can't actually be decoded is rejected with a clear error rather than a 500 deep in a resize call.

Thumbnail pipeline. The canonical day-to-day pattern is: controller validates → file lands on a Storage disk → a queued job loads it via ImageHelper, resizes, and writes the derivative to the same disk → the model stores the derivative path. Keep the absolute local path (Storage::path()) for the library and the disk-relative path for the database; don't mix the two.

Format-specific behaviour. Use the new classes where format matters — choosing output quality for JPEG, preserving transparency for PNG/GIF, choosing between imagewebp and a JPEG fallback. Keeping this behind the typed classes means you can add a WEBPFile later without touching call sites, and it gives you a natural place to hang per-format defaults.

Caching and re-processing. Store the source file, generate derivatives on demand, and key the cache on a hash of (source path, width, height, format). When you bump resize settings, change the key rather than trying to invalidate in place — it saves you from a nasty partial-invalidation bug.

Testing. Use real fixture files, not mocks. A tiny 1×1 PNG, a 2×2 GIF (with and without transparency), an EXIF-rotated JPEG, and a minimal SVG exercise nearly every branch. Storage::fake() works fine as long as you pass the real absolute path into the library.

Gotchas and Tips

Check the GD vs Imagick requirement. The package depends on a PHP image extension. Verify which one your Laravel deployment has — GD is more common but Imagick handles CMYK JPEGs, colour profiles, and animated GIFs better. Different extensions produce different pixel output, so golden-image tests can pass locally and fail in CI.

Memory limits are the classic production failure. Decoding a large JPEG costs roughly width × height × 4 bytes before you resize. A 6000×4000 upload is ~96 MB. Process large images in a queued worker with its own memory_limit, and enforce an upload size/dimension cap in validation before the library ever sees the file.

SVGs are executable documents, not just images. Never serve a user-uploaded SVG from your own origin without sanitising it (strip <script>, on* handlers, external <use href>, and DOCTYPE/entity tricks). SVGFile gives you object identity, not a sanitiser — pair it with a dedicated sanitiser or serve user SVGs from a separate, Content-Disposition: attachment-style origin.

Animated GIFs and multi-page TIFFs. Most resize paths operate on the first frame. If animation matters, detect it before you flatten and either pass through untouched or reject the upload.

EXIF orientation. Phone photos carry an orientation tag that the pixel data ignores. Auto-rotate on ingest, then strip EXIF — otherwise portrait photos render sideways and you leak GPS coordinates from user uploads.

Don't trust extensions. photo.jpg that's actually a PNG will still load if you sniff content, and will confuse code that branches on the filename. Branch on the typed class, never on pathinfo().

Upgrade safety for 1.2.0. This is a minor release adding classes, so it's additive and should be safe within your existing ^1.1 constraint — but if you've written your own file-type subclasses or switch statements over format strings, re-check them against the new classes to avoid duplicate/conflicting type resolution. Run your image fixture tests after the bump.

Extension points. The most useful hook is subclassing the base file class to add a format the library doesn't ship (WEBP/AVIF), or to attach app-specific metadata. Do that in one place — a small factory wrapper around ImageHelper — rather than sprinkling instanceof chains across controllers. That wrapper is also where you centralise memory limits, sanitiser calls, and EXIF stripping, which is the single highest-leverage refactor for keeping this package tidy in a real Laravel codebase.

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.
3mdikram/worldmoneywords
snowsoft/config
itmosoft/laravel-subscriptions
larva/laravel-ai-qwen
diephp/sequences
users-au/socialite-provider
twidpay/twid-logger
mrnewport/laravel-plaid
mrnewport/laravel-repo
mrnewport/laravel-docsign
mrnewport/laravel-stow
mrnewport/laravel-flow
mrnewport/laravel-priceable
mrnewport/laravel-nestedterms
fredmeng/laravel-apidoc-generator
itstructure/laravel-multilingual-tools
pdustdar/elasticsearch
markupai/php-sdk
rlacerda83/lumem-microservice-shipment
uni-method/symfony-lib