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

Color Extractor Laravel Package

league/color-extractor

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation:

    composer require league/color-extractor
    

    Ensure ext-gd is enabled in your PHP environment.

  2. First Use Case: Extract colors from an uploaded image in a Laravel controller:

    use League\ColorExtractor\ColorExtractor;
    use League\ColorExtractor\Palette;
    
    public function extractColors(Request $request)
    {
        $imagePath = $request->file('image')->getRealPath();
        $palette = Palette::fromFilename($imagePath);
        $colors = (new ColorExtractor($palette))->extract(5);
        return response()->json($colors);
    }
    
  3. Where to Look First:

    • Palette class: Core for loading images and generating color data.
    • ColorExtractor class: Extracts representative colors from a palette.
    • Color helper: Converts between integer and hex representations.

Implementation Patterns

Usage Patterns

  1. Extracting Colors from Uploads:

    // In a Laravel controller
    public function handleUpload(Request $request)
    {
        $image = $request->file('image');
        $palette = Palette::fromFilename($image->getRealPath());
        $topColors = $palette->getMostUsedColors(3);
        return view('result', ['colors' => $topColors]);
    }
    
  2. URL-Based Extraction (Async): Use Laravel Queues to process remote images:

    // Job
    class ExtractRemoteColorsJob implements ShouldQueue
    {
        public function handle()
        {
            $palette = Palette::fromUrl('https://example.com/image.jpg');
            $colors = (new ColorExtractor($palette))->extract(5);
            // Store in database or cache
        }
    }
    
    // Dispatch
    ExtractRemoteColorsJob::dispatch();
    
  3. Dynamic Theming: Generate CSS variables from extracted colors:

    public function getThemeColors(Request $request)
    {
        $palette = Palette::fromFilename($request->file('theme_image')->getRealPath());
        $colors = $palette->getMostUsedColors(4);
        $cssVars = collect($colors)->map(fn($color) => "--color-$color: " . Color::fromIntToHex($color) . ";");
        return response()->json(['css' => $cssVars->implode(' ')], 200);
    }
    
  4. Transparency Handling: Blend transparent pixels with a background color:

    $palette = Palette::fromFilename($imagePath, Color::fromHexToInt('#FFFFFF'));
    

Workflows

  1. Batch Processing: Use Laravel’s Artisan commands to process a directory of images:

    // app/Console/Commands/ProcessImages.php
    public function handle()
    {
        $images = Storage::disk('public')->files('images');
        foreach ($images as $image) {
            $palette = Palette::fromFilename(storage_path('app/' . $image));
            $colors = (new ColorExtractor($palette))->extract(3);
            // Save to database
        }
    }
    
  2. Caching Palettes: Cache extracted palettes to avoid reprocessing:

    public function getCachedPalette($imagePath)
    {
        return Cache::remember("palette-{$imagePath}", now()->addHours(1), function() use ($imagePath) {
            return Palette::fromFilename($imagePath);
        });
    }
    
  3. Integration with Laravel Filesystem: Read images from S3 or other disks:

    $path = Storage::disk('s3')->path('uploads/product.jpg');
    $palette = Palette::fromFilename($path);
    

Integration Tips

  1. Validation: Validate image types and GD extension before processing:

    if (!extension_loaded('gd')) {
        throw new RuntimeException('GD extension is required.');
    }
    $request->validate([
        'image' => 'required|image|mimes:jpeg,png,jpg,gif|max:2048',
    ]);
    
  2. Error Handling: Gracefully handle file/permission errors:

    try {
        $palette = Palette::fromFilename($path);
    } catch (InvalidArgumentException $e) {
        Log::error("Color extraction failed: " . $e->getMessage());
        return back()->withError('Invalid image file.');
    }
    
  3. Testing: Mock image inputs using Palette::fromContents():

    public function testColorExtraction()
    {
        $imageData = file_get_contents(__DIR__ . '/test-image.png');
        $palette = Palette::fromContents($imageData);
        $this->assertCount(5, $palette->getMostUsedColors(5));
    }
    

Gotchas and Tips

Pitfalls

  1. GD Extension Dependency:

    • Pitfall: Missing ext-gd will cause runtime errors.
    • Fix: Validate extension in bootstrap/app.php or use a fallback (e.g., Imagick).
  2. Transparency Handling:

    • Pitfall: Default behavior discards transparent pixels, which may not be desired for design tools.
    • Fix: Explicitly set a background color for blending:
      $palette = Palette::fromFilename($path, Color::fromHexToInt('#FFFFFF'));
      
  3. Large Images:

    • Pitfall: Processing high-resolution images (e.g., 4K) can spike memory usage.
    • Fix: Resize images before extraction using Laravel Intervention:
      $image = Image::make($request->file('image')->getRealPath())->resize(800, null);
      $image->save($tempPath);
      $palette = Palette::fromFilename($tempPath);
      
  4. URL Fetching:

    • Pitfall: Palette::fromUrl() requires cURL or allow_url_fopen.
    • Fix: Configure Laravel’s HTTP client or use a queue job with retries.
  5. Color Count Mismatches:

    • Pitfall: getColorCount() may return 0 for non-existent colors.
    • Fix: Check if color exists first:
      $colorInt = Color::fromHexToInt('#000000');
      $count = $palette->getColorCount($colorInt) ?? 0;
      

Debugging

  1. Log Palette Data: Inspect extracted colors for debugging:

    foreach ($palette as $color => $count) {
        Log::debug("Color: " . Color::fromIntToHex($color) . ", Count: " . $count);
    }
    
  2. Check Image Validity: Verify images are readable before processing:

    if (!is_readable($imagePath)) {
        throw new RuntimeException("Image file is not readable.");
    }
    
  3. Memory Limits: Increase PHP memory limit for large images:

    ini_set('memory_limit', '512M');
    

Tips

  1. Optimize for Performance:

    • Cache palettes in Redis or database.
    • Use Laravel Queues for async processing of large images.
  2. Extend Functionality:

    • Create a custom ColorExtractor decorator to add domain-specific logic:
      class BrandColorExtractor extends ColorExtractor
      {
          public function extractBrandColors($limit = 3)
          {
              $colors = parent::extract($limit);
              return collect($colors)->filter(fn($color) => $this->isBrandColor($color));
          }
      }
      
  3. Handle Edge Cases:

    • Monochrome Images: Ensure at least one color is returned:
      $colors = $extractor->extract(5);
      if (empty($colors)) {
          $colors = [$palette->getMostUsedColor()];
      }
      
  4. Laravel Service Container: Bind the extractor as a singleton for reuse:

    $this->app->singleton(ColorExtractor::class, function ($app) {
        $imagePath = $app['request']->file('image')->getRealPath();
        return new ColorExtractor(Palette::fromFilename($imagePath));
    });
    
  5. Testing Transparency: Test with images containing transparency to ensure blending works as expected:

    public function testTransparentImage()
    {
        $pngWithAlpha = file_get_contents(__DIR__ . '/transparent-image.png');
        $palette = Palette::fromContents($pngWithAlpha, Color::fromHexToInt('#00FF00'));
        $this->assertNotEmpty($palette->getMostUsedColors(1));
    }
    
  6. Fallback for Missing GD: Use a queue job with a fallback to a cloud service:

    class ExtractColorsJob implements ShouldQueue
    {
        public function handle()
        {
            if (extension_loaded('gd')) {
                $palette = Palette::fromFilename($
    
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.
besmartand-pro/php-quality-config
sentix/ai-chatbot
terminal42/code-quality-tools
codifyo/ts-generator-bundle
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