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 Crop Bundle Laravel Package

rares/image-crop-bundle

Symfony bundle for cropping and resizing images in PHP applications. It helps handle uploaded files, define crop dimensions, generate thumbnails, and integrate image-crop workflows into forms and templates with minimal configuration.

View on GitHub
Deep Wiki
Context7

Getting Started

This is a Symfony bundle, not a Laravel package — so if you're coming from Laravel, treat it as a reference implementation rather than a composer require-and-go dependency. The day-to-day workflow it targets is: an entity has an image field managed by VichUploaderBundle, and the user needs to crop that image in-browser before it's persisted.

Minimal setup in a Symfony app:

  1. composer require rares/image-crop-bundle (check the repo's composer.json for the vich/uploader-bundle and Symfony version constraints first — this is a low-traffic package, so pinning matters).
  2. Register Rares\ImageCropBundle\ImageCropBundle (or whatever the namespace is — confirm in the bundle class) in config/bundles.php.
  3. Ensure vich/uploader-bundle is installed and your entity's @Vich\UploadableField mapping exists — this bundle does not replace Vich, it layers a crop step on top.
  4. Publish/import the Cropper.js assets. There is no AssetMapper/Webpack Encore recipe shipped, so you wire cropperjs (CSS + JS) yourself and include the bundle's template/twig partial or copy its JS glue.

Look first at: the bundle's Resources/views (the crop modal/partial), the Form Type if one ships, and the entity/annotation requirements documented in the README. The first use case to validate end-to-end: a single-image upload with a crop modal that writes back cropX/cropY/cropWidth/cropHeight (or equivalent) onto your entity alongside the Vich-managed file.

Implementation Patterns

Entity + Vich + crop metadata. The canonical pattern is a Vich UploadableField for the file plus four persisted scalar columns for the crop box (x, y, width, height) — or a single JSON column if you prefer. The bundle's JS submits the crop rect; your entity setter stores it. Actual cropping happens either client-side (Cropper's getCroppedCanvas().toBlob() before upload) or server-side in a post-persist listener. Decide which before wiring anything.

Client-side crop (recommended for this bundle). Let Cropper generate the cropped blob and hand it to Vich as the uploaded file. This keeps you off image-processing extensions (GD/Imagick) and matches how the jQuery Cropper demo works. Downside: no re-crop later without re-uploading the original — keep the source image around if re-editing is a requirement.

Server-side crop. If you must preserve the original, use the crop rect to Image::crop() (Intervention Image) in a Doctrine lifecycle callback or a dedicated service after Vich persists the file. This is the pattern to reach for if you're porting the idea to Laravel — swap Vich for Storage::put + a UploadedFile handler, and run the same crop-rect math in a job or observer.

Form integration. Wrap the file input in a form type that renders the crop partial, and add a hidden field for the crop coordinates. Validate on submit that the rect lies inside the image bounds — Cropper won't guarantee it if the user resizes the container oddly.

Porting to Laravel. If the goal is to reuse this in a Laravel app: drop the bundle, keep Cropper.js, and replace the crop step with a FormRequest that accepts crop: {x,y,w,h} plus the UploadedFile, then crop in a Job/Action before Storage::disk()->put(). The Vich coupling and Symfony DI are the only parts that don't transfer.

Gotchas and Tips

It's Symfony-only and effectively unmaintained. Zero stars, zero dependents, and a Bitbucket-hosted repo means: no Packagist safety net you can rely on, no issue tracker traffic to learn from, and no security advisories. Audit the source before production; it's small enough to read in an hour.

Vich version drift is the most likely breakage. Vich moved its annotation/attribute conventions across 1.x → 2.x. If the bundle pins an old Vich, your Symfony version may not satisfy it. Check composer.json constraints and prefer the newer #[Vich\UploadableField] attributes in your own entity regardless of what the README shows.

Cropper.js v1 vs v2 API. Cropper went jQuery-plugin (v0/v1) → standalone (v2). The bundle's description explicitly says "Cropper jQuery library," so it expects the jQuery-plugin era. If you pull a modern cropperjs from npm, the constructor and event names differ (cropend vs crop payloads, getCroppedCanvas options). Pin the version the bundle's JS was written against or budget time to rewrite the glue.

Asset pipeline. No Encore/AssetMapper config ships. In Symfony 6+/7 with AssetMapper you must add cropperjs via importmap manually and expose the Cropper global the bundle's inline JS expects. In Laravel/Vite, import Cropper from 'cropperjs' and mount it in a small Alpine or vanilla module — don't try to reuse the bundle's Twig partial.

Debugging crop coordinates. The usual failure is a mismatch between the displayed image size and the natural size — crop math must scale by naturalWidth / displayedWidth. Log the rect and the source dimensions together; most "crop is offset" bugs are container CSS (max-width: 100%) rather than the library.

Extension points to lean on. If you keep the bundle, hook the post-crop step via a Symfony event listener on Vich's POST_UPLOAD (or your own Doctrine postPersist) rather than editing bundle files — the repo is unlikely to accept upstream patches or to merge your fork cleanly.

Recommendation: for a new Laravel project, don't adopt this — reimplement the ~50 lines of Cropper glue yourself. For an existing Symfony app already on Vich, it's a thin convenience layer worth reading before deciding to vendor it.

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.
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core