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

Gif Laravel Package

intervention/gif

Native PHP GIF encoder/decoder for GIF data streams with no image extensions required. Decode files or binary content, and build animated GIFs via a Builder. Includes optional GD-based Splitter to extract frames into GDImage objects. Supports PHP 8.3+.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation:

    composer require intervention/gif
    

    Ensure your project uses PHP 8.3+ and has the GD extension (required for Splitter class).

  2. First Use Case:

    • Decode a GIF:

      use Intervention\Gif\Decoder;
      
      $gifData = Decoder::decode(storage_path('app/animation.gif'));
      // $gifData is an Intervention\Gif\GifDataStream object
      
    • Encode a GIF:

      use Intervention\Gif\Builder;
      
      $gif = Builder::canvas(32, 32)
          ->addFrame(storage_path('app/frame1.gif'), 0.5)
          ->addFrame(storage_path('app/frame2.gif'), 0.5)
          ->setLoops(3);
      
      $encodedGif = $gif->encode();
      file_put_contents(storage_path('app/output.gif'), $encodedGif);
      
  3. Where to Look First:

    • Decoder: src/Decoder.php for parsing GIFs.
    • Builder: src/Builder.php for creating GIFs.
    • Blocks: src/Blocks/ for GIF metadata (e.g., GlobalColorTable, GraphicControlExtension).
    • Tests: tests/Unit/ for usage examples and edge cases.

Implementation Patterns

Usage Patterns

  1. Decoding Workflow:

    • Use Decoder::decode() for file paths or binary content.
    • Access frames via $gifData->getFrames() (returns GifFrame[]).
    • Extract metadata (e.g., loop count, delays) from $gifData->getLogicalScreenDescriptor() or $gifData->getGraphicControlExtensions().
    $gif = Decoder::decode($binaryContent);
    foreach ($gif->getFrames() as $frame) {
        $delay = $frame->getGraphicControlExtension()->getDelayTime();
        // Process frame...
    }
    
  2. Encoding Workflow:

    • Start with Builder::canvas(width, height) for a blank GIF.
    • Add frames sequentially with addFrame(path, delay, left, top).
    • Configure loops with setLoops(int) (0 = infinite).
    • Encode with encode() to get binary data.
    $gif = Builder::canvas(100, 100)
        ->addFrame('frame1.png', 1.0, 0, 0)
        ->addFrame('frame2.png', 1.0, 0, 0)
        ->setLoops(0); // Infinite loop
    
    $binaryGif = $gif->encode();
    
  3. Integration with Laravel:

    • Service Provider:
      // app/Providers/GifServiceProvider.php
      public function register()
      {
          $this->app->bind(Decoder::class, function () {
              return new Decoder();
          });
          $this->app->bind(Builder::class, function () {
              return new Builder();
          });
      }
      
    • Validation:
      use Illuminate\Validation\Rule;
      
      $rules = [
          'gif' => ['required', Rule::exists('storage', 'path')->where('extension', 'gif')],
      ];
      
    • Queue Jobs:
      // app/Jobs/EncodeGifJob.php
      public function handle()
      {
          $gif = Builder::canvas(200, 200)
              ->addFrame('frame1.png', 0.5)
              ->encode();
      
          Storage::put('encoded.gif', $gif);
      }
      
  4. Frame Extraction with GD:

    • Use Splitter::split() to break animated GIFs into GDImage objects (for further processing with Intervention\Image):
      use Intervention\Gif\Splitter;
      
      $frames = Splitter::split($gifPath);
      foreach ($frames as $frame) {
          $image = Image::gd($frame);
          $image->resize(100, 100);
          // Save or process...
      }
      

Workflows

  1. Dynamic GIF Generation:

    • Generate GIFs on-the-fly for user-specific content (e.g., "like" animations).
    • Example: Combine user-uploaded images with a template GIF.
      $template = Decoder::decode('template.gif');
      $userImage = Image::make($userUpload)->resize(50, 50);
      $builder = Builder::canvas($template->getWidth(), $template->getHeight())
          ->addFrame($userImage->toGD(), 1.0)
          ->setLoops(1);
      
  2. GIF Validation:

    • Validate GIFs before processing (e.g., reject corrupted files):
      try {
          $gif = Decoder::decode($file);
      } catch (\Intervention\Gif\Exceptions\GifException $e) {
          throw ValidationException::withMessages(['gif' => 'Invalid GIF file.']);
      }
      
  3. Metadata Preservation:

    • Ensure GIFs retain delays, loops, and transparency for accessibility:
      $gif = Decoder::decode($file);
      $delay = $gif->getGraphicControlExtensions()[0]->getDelayTime();
      $loopCount = $gif->getLogicalScreenDescriptor()->getLoopCount();
      
  4. Batch Processing:

    • Process multiple GIFs using Laravel’s collect() and queues:
      $paths = Storage::disk('uploads')->files('*.gif');
      foreach ($paths as $path) {
          EncodeGifJob::dispatch($path)->onQueue('gifs');
      }
      

Gotchas and Tips

Pitfalls

  1. GD Dependency:

    • The Splitter class requires GD. If GD is unavailable, frame extraction will fail.
    • Fix: Check for GD at runtime:
      if (!extension_loaded('gd')) {
          throw new \RuntimeException('GD extension is required for frame extraction.');
      }
      
  2. Corrupted GIFs:

    • The package throws exceptions for malformed GIFs. Handle gracefully in Laravel:
      try {
          $gif = Decoder::decode($file);
      } catch (\Intervention\Gif\Exceptions\GifException $e) {
          Log::error("Invalid GIF: {$e->getMessage()}");
          return response()->json(['error' => 'Invalid GIF'], 400);
      }
      
  3. Frame Delays:

    • Delays are in hundredths of a second (e.g., 100 = 1 second). Convert carefully:
      $delay = $frame->getGraphicControlExtension()->getDelayTime() / 100; // Convert to seconds
      
  4. Memory Limits:

    • Large GIFs (e.g., >10MB) may exceed PHP’s memory limit.
    • Fix: Use chunked processing or increase memory_limit:
      ini_set('memory_limit', '512M');
      
  5. Loop Count vs. Repetitions:

    • setLoops(0) = infinite loop. setLoops(1) = play once.
    • Gotcha: Older GIFs may use "repetitions" (deprecated). Use getLoopCount() to check.

Debugging

  1. Inspect GIF Metadata:

    • Dump the GifDataStream object to debug:
      $gif = Decoder::decode($file);
      dd($gif->getLogicalScreenDescriptor(), $gif->getGraphicControlExtensions());
      
  2. Validate Binary Data:

    • Ensure encoded data is valid:
      $binary = $builder->encode();
      if (empty($binary) || strlen($binary) < 100) {
          throw new \RuntimeException('Encoding failed: empty output.');
      }
      
  3. Check for GD Errors:

    • If Splitter::split() fails, verify GD is installed and the file is a valid GIF:
      if (!function_exists('gd_info')) {
          throw new \RuntimeException('GD extension not available.');
      }
      

Tips

  1. Leverage Intervention Image:

    • Combine with Intervention\Image to resize frames before encoding:
      $frame = Image::make($framePath)->resize(200, 200);
      $builder->addFrame($frame->toGD(), 0.5);
      
  2. Cache Decoded GIFs:

    • Cache GifDataStream objects to avoid reprocessing:
      $gif = Cache::remember("gif_{$path}", now()->addHours(1), function () use ($path) {
          return Decoder::decode($path);
      });
      
  3. Use Laravel Events:

    • Trigger events for GIF encoding
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.
davejamesmiller/laravel-breadcrumbs
artisanry/parsedown
christhompsontldr/phpsdk
enqueue/dsn
bunny/bunny
enqueue/test
enqueue/null
enqueue/amqp-tools
milesj/emojibase
bower-asset/punycode
bower-asset/inputmask
bower-asset/jquery
bower-asset/yii2-pjax
laravel/nova
spatie/laravel-mailcoach
spatie/laravel-superseeder
laravel/liferaft
nst/json-test-suite
danielmiessler/sec-lists
jackalope/jackalope-transport