Weave Code
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

Crop Imagick Laravel Package

ahonymous/crop-imagick

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation

    composer require ahonymous/crop-imagick
    

    Enable the bundle in config/bundles.php (Symfony) or AppKernel.php (legacy):

    Ahonymous\CropImagickBundle\CropImagickBundle::class => ['all' => true],
    
  2. Configuration Add to config/packages/crop_imagick.yaml:

    crop_imagick:
        upload_dir: '%kernel.project_dir%/public/uploads'
        allowed_formats: ['jpg', 'jpeg', 'png', 'gif']
    
  3. First Use Case Create a controller to handle image uploads and cropping:

    use Ahonymous\CropImagickBundle\CropImagick;
    use Symfony\Component\HttpFoundation\Request;
    
    public function cropImage(Request $request, CropImagick $cropImagick)
    {
        $file = $request->files->get('image');
        $cropData = json_decode($request->request->get('crop'), true);
    
        $result = $cropImagick->crop($file, $cropData);
        return new JsonResponse(['path' => $result]);
    }
    
  4. Frontend Integration Use a library like Cropper.js to send crop coordinates via AJAX to the endpoint above.


Implementation Patterns

Workflow: Upload and Crop

  1. File Upload Handle file uploads via Symfony's File component or a form with enctype="multipart/form-data".

  2. Crop Data Extraction Extract crop coordinates (e.g., x, y, width, height) from frontend and send as JSON:

    {
        "x": 100,
        "y": 50,
        "width": 200,
        "height": 200
    }
    
  3. Crop Processing Use the CropImagick service:

    $croppedPath = $cropImagick->crop($file, $cropData, [
        'output_format' => 'jpg',
        'quality' => 80,
    ]);
    
  4. Response Handling Return the path to the cropped image or a redirect to the processed image:

    return $this->redirect($croppedPath);
    

Integration with Forms

Use Symfony's File type in forms:

$builder->add('image', FileType::class, [
    'label' => 'Upload Image',
    'mapped' => false,
    'required' => true,
]);

For AJAX submissions, validate and process the crop data manually.


Batch Processing

For bulk cropping (e.g., admin panel):

public function batchCrop(Request $request, CropImagick $cropImagick)
{
    $files = $request->files->get('images');
    $results = [];

    foreach ($files as $file) {
        $cropData = [...] // Fetch crop data per file
        $results[] = $cropImagick->crop($file, $cropData);
    }

    return new JsonResponse($results);
}

Custom Output Paths

Override the default upload directory per request:

$customPath = $cropImagick->crop($file, $cropData, [
    'upload_dir' => '/custom/path',
]);

Gotchas and Tips

Pitfalls

  1. Imagick Extension Missing Ensure ext-imagick is installed and enabled. Test with:

    php -m | grep imagick
    

    If missing, install via:

    pecl install imagick
    

    or system package manager (e.g., apt-get install php-imagick).

  2. File Permissions The upload_dir must be writable by the PHP process. Set permissions:

    chmod -R 775 /path/to/upload_dir
    
  3. Memory Limits Large images may exceed PHP's memory_limit. Increase it in php.ini or .htaccess:

    memory_limit = 512M
    
  4. Image Format Restrictions The bundle enforces allowed_formats. To bypass (not recommended):

    crop_imagick:
        allowed_formats: ['*'] # Allows all formats
    

Debugging

  1. Check Crop Data Validate crop coordinates before processing:

    if (!isset($cropData['x'], $cropData['y'], $cropData['width'], $cropData['height'])) {
        throw new \InvalidArgumentException('Invalid crop data');
    }
    
  2. Log Errors Wrap calls in try-catch to log Imagick exceptions:

    try {
        $result = $cropImagick->crop($file, $cropData);
    } catch (\Exception $e) {
        \Log::error('Crop failed: ' . $e->getMessage());
        throw $e;
    }
    
  3. Verify Output Use file_exists() to confirm cropped files are saved:

    if (!file_exists($croppedPath)) {
        throw new \RuntimeException('Cropped file not generated');
    }
    

Extension Points

  1. Custom Filters Extend the bundle by creating a subclass of CropImagick:

    class CustomCropImagick extends CropImagick
    {
        public function applyFilters($path)
        {
            $this->applyImagickFilter($path, 'blur', '0x1');
            return $path;
        }
    }
    

    Register as a service in services.yaml:

    services:
        App\Service\CustomCropImagick:
            arguments:
                $uploadDir: '%crop_imagick.upload_dir%'
            tags: ['crop_imagick.cropper']
    
  2. Event Listeners Listen for crop events (if the bundle supports them) to add pre/post-processing:

    // Example for hypothetical events
    $eventDispatcher->addListener('crop_imagick.pre_crop', function ($event) {
        $event->setOption('quality', 90);
    });
    
  3. Configuration Overrides Override bundle config dynamically:

    $container->getParameterBag()->set('crop_imagick.upload_dir', '/new/path');
    

Performance Tips

  1. Cache Crop Data Store crop coordinates in the database to avoid reprocessing:

    $cropData = $entityRepository->findCropData($entityId);
    
  2. Use Placeholders Generate placeholders for thumbnails to reduce load:

    $cropImagick->resize($file, 200, 200);
    
  3. Async Processing Offload cropping to a queue (e.g., Symfony Messenger) for large batches:

    $message = new CropImageMessage($file, $cropData);
    $bus->dispatch($message);
    
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.
terminal42/code-quality-tools
codifyo/ts-generator-bundle
andydefer/laravel-cluster
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky