Search code examples
intervention

Replace a color in intervention image


I want to convert a user-uploaded image to a page background, by merging it with the background color.

To do that effect, I wanted to set the image to grayscale, then replacing the colors to match my background color (which is orange), so I wanted to replace the colorss (black matching my background's color, then each gray level faded to another clearer value).

The grescale() method is OK, but I don't know how to make the replacement. I tried the colorize function, but it only seems to brighten the image too much, even if I darken the image before with contrast(). LimitColors() didn't work neither.

How could I get the effect I want ?


Solution

  • I managed to get the display I wanted, using this method :

    • create an image the size of my main image, filled with the color I want
    • use my main image as a mask for the first image
    • save as PNG (I put the emphasis here because my tests didn't work because I was using the default JPEG export).

    Using intervention's filters to make it easier to use elsewhere, here's my result :

    <?php
    
    namespace App\ImageFilters;
    
    use Intervention\Image\Filters\FilterInterface;
    use Intervention\Image\Image;
    use Intervention\Image\ImageManager;
    
    class MyFilter implements FilterInterface
    {
        /** @var ImageManager */
        private $imageManager;
    
        const BACKGROUND_COLOR = '#FCB65B';
    
        public function __construct()
        {
            $this->imageManager = new ImageManager();
        }
    
        public function applyFilter(Image $image)
        {
            $height = $image->getHeight();
            $width = $image->getWidth();
    
            return $this->imageManager
                ->canvas($width, $height)
                ->fill(self::BACKGROUND_COLOR)
                ->mask($image, false);
        }
    
    }
    

    It's used like this in my image management script:

    $image = $image->filter(New MyFilter());
    

    Edit before posting:

    • I was trying to convert the main image to black&white with greyscale()but after omitting it it happens that there is no impact with the mask function.
    • I brighten a little the main image before applying it as a mask, I think it works best for my purposes.

      /* replace the mask call with this one */ ->mask($image->brightness(25), false);