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

Image Bundle Laravel Package

crd2i/image-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    • For Symfony 2.1+, add to composer.json:
      "require": {
          "paradigmate/image-bundle": "dev-master"
      }
      
    • Run composer update.
    • Enable the bundle in app/AppKernel.php:
      new Paradigma\Bundle\ImageBundle\ParadigmaImageBundle(),
      
  2. Configuration:

    • Add to app/config/config.yml:
      paradigmate_image:
          default_driver: gd  # or 'imagick' if available
      
  3. First Use Case:

    • Inject the service in a controller:
      use Paradigma\Bundle\ImageBundle\Image\ImageResizer;
      use Paradigma\Bundle\ImageBundle\Image\ImageSize;
      
      class ImageController extends Controller
      {
          public function resizeAction($sourcePath, $destinationPath, $size)
          {
              $resizer = $this->get('image_resizer');
              $resizer->resize(
                  $sourcePath,
                  $destinationPath,
                  new ImageSize($size, $size),
                  ImageResizer::RESIZE_TYPE_CROP
              );
              return new Response('Image resized!');
          }
      }
      
    • Route it:
      # app/config/routing.yml
      image_resize:
          path:     /resize/{source}/{destination}/{size}
          defaults: { _controller: AppBundle:Image:resize }
      

Implementation Patterns

Common Workflows

  1. Dynamic Thumbnail Generation:

    • Use middleware to auto-generate thumbnails on upload:
      // In a FormType or EventListener
      $resizer->resize(
          $uploadedFile->getPathname(),
          $destinationPath,
          new ImageSize(200, 200),
          ImageResizer::RESIZE_TYPE_FIT
      );
      
  2. Lazy-Loading with Cache:

    • Store resized images in public/uploads/thumbs/ and cache responses:
      $cacheKey = md5($sourcePath . $size);
      $cachedPath = $this->getParameter('kernel.root_dir') . '/../web/uploads/thumbs/' . $cacheKey;
      if (!file_exists($cachedPath)) {
          $resizer->resize($sourcePath, $cachedPath, new ImageSize($size, $size));
      }
      return $this->renderView('image.html.twig', ['path' => '/uploads/thumbs/' . $cacheKey]);
      
  3. Batch Processing:

    • Process multiple images in a queue (e.g., with Symfony Messenger):
      foreach ($imagePaths as $path) {
          $this->get('image_resizer')->resize(
              $path,
              $path . '_thumb',
              new ImageSize(100, 100),
              ImageResizer::RESIZE_TYPE_CROP
          );
      }
      

Integration Tips

  • Doctrine Entities:

    • Add a getThumbnailPath() method to your entity:
      public function getThumbnailPath($size = 100)
      {
          return $this->getPath() . '_thumb_' . $size . '.jpg';
      }
      
    • Use a Lifecycle Callback to auto-generate thumbnails:
      use Doctrine\ORM\Mapping as ORM;
      
      /**
       * @ORM\PrePersist
       * @ORM\PreUpdate
       */
      public function generateThumbnail()
      {
          if ($this->getPath()) {
              $resizer = $this->getContainer()->get('image_resizer');
              $resizer->resize(
                  $this->getPath(),
                  $this->getThumbnailPath(),
                  new ImageSize(100, 100)
              );
          }
      }
      
  • Twig Filters:

    • Create a custom Twig filter for dynamic image URLs:
      // src/AppBundle/Twig/AppExtension.php
      class AppExtension extends \Twig_Extension
      {
          public function getFilters()
          {
              return [
                  new \Twig_SimpleFilter('resize_image', [$this, 'resizeImageFilter']),
              ];
          }
      
          public function resizeImageFilter($path, $size)
          {
              return $this->container->get('router')->generate(
                  'image_resize',
                  ['source' => basename($path), 'destination' => 'thumb_' . $size, 'size' => $size]
              );
          }
      }
      
    • Use in Twig:
      <img src="{{ path|resize_image(200) }}" />
      

Gotchas and Tips

Pitfalls

  1. File Permissions:

    • Ensure the web server user (e.g., www-data) has write permissions to the destination directory.
    • Fix: Run chmod -R 775 public/uploads/thumbs and chown -R www-data:www-data public/uploads/thumbs.
  2. GD vs. Imagick:

    • The bundle defaults to GD, but Imagick (if installed) provides better quality and features.
    • Fix: Set default_driver: imagick in config if available.
  3. Memory Limits:

    • Resizing large images (e.g., 10MB+) may hit PHP’s memory_limit.
    • Fix: Increase memory_limit in php.ini or use Imagick for better memory handling.
  4. EXIF Orientation:

    • Images with EXIF data (e.g., from mobile devices) may appear rotated.
    • Fix: Enable EXIF support in config:
      paradigmate_image:
          exif_aware: true
      
  5. Race Conditions:

    • Concurrent requests to resize the same image can corrupt files.
    • Fix: Use a lock (e.g., flock) or a queue system (Symfony Messenger).

Debugging

  • Check Logs:

    • Enable debug mode (APP_DEBUG=true) to see errors in var/log/dev.log.
    • Common issues: Missing GD/Imagick, invalid source paths, or permission errors.
  • Validate Input:

    • Always check if $sourcePath exists before resizing:
      if (!file_exists($sourcePath)) {
          throw new \RuntimeException("Source image not found: {$sourcePath}");
      }
      

Extension Points

  1. Custom Resize Types:

    • Extend the ImageResizer class to add custom resize logic (e.g., "stretch to fill"):
      class CustomImageResizer extends ImageResizer
      {
          const RESIZE_TYPE_STRETCH = 'stretch';
      
          protected function resizeStretch($source, $destination, ImageSize $size)
          {
              // Custom logic here
          }
      }
      
    • Register as a service:
      services:
          custom_image_resizer:
              class: AppBundle\Service\CustomImageResizer
              arguments: ['@image_resizer.driver.gd']
      
  2. Driver Overrides:

    • Replace the default GD/Imagick driver with a custom one:
      // src/AppBundle/DependencyInjection/Compiler/CustomImagePass.php
      public function process(ContainerBuilder $container)
      {
          $definition = $container->findDefinition('image_resizer.driver.gd');
          $definition->setClass('AppBundle\Image\CustomDriver');
      }
      
  3. Event Listeners:

    • Listen for resize events to log or validate images:
      // src/AppBundle/EventListener/ImageListener.php
      class ImageListener implements EventSubscriberInterface
      {
          public static function getSubscribedEvents()
          {
              return [
                  'image_resizer.pre_resize' => 'onPreResize',
                  'image_resizer.post_resize' => 'onPostResize',
              ];
          }
      
          public function onPreResize(GetResponseEvent $event)
          {
              // Validate image before resize
          }
      }
      

Performance Tips

  • Cache Busters:

    • Append a query string to resized images to bypass cache:
      return '/uploads/thumbs/' . $cacheKey . '?v=' . filemtime($sourcePath);
      
  • Predefined Sizes:

    • Define common sizes in config to avoid recreating ImageSize objects:
      paradigmate_image:
          sizes:
              thumbnail: 100
              medium: 500
              large: 1200
      
    • Use in code:
      $size = new ImageSize($this->getParameter('paradigmate_image.sizes.thumbnail'));
      
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.
croct/coding-standard
croct/plug-php
nqxcode/phpmorphy
boundwize/pyrameter
develia/commons
dmstr/symfony-system-resources-bundle
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony
renatomarinho/laravel-page-speed
develia/geo-bundle
austinheap/laravel-database-encryption
dreamzy/livewire-charts
touchestate-sdk/php-sdk
22h/doctrine-garbage-collection-bundle
imbo/imbo-coding-standard
visualbuilder/filament-lottie
servicioslineaonce/starter-kit
atomcoder/laravel-reorderable
irajul/filament-shadcn-theme
agtp/agtp-php