Last active
January 4, 2022 07:05
-
-
Save nicholasc/e263d976d3aa0304537ea2f075ba7906 to your computer and use it in GitHub Desktop.
A Duotone filter for Imagine PHP library.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
use Imagine\Image\Point; | |
use Imagine\Image\ImageInterface; | |
use Imagine\Filter\FilterInterface; | |
use Imagine\Filter\Advanced\OnPixelBased; | |
use Imagine\Image\Palette\Color\RGB; | |
/** | |
* Duotone | |
* | |
* A filter class for creating duotone images with Imagine. | |
* | |
* @author Nicholas Charbonneau | |
* @license http://opensource.org/licenses/MIT | |
* @link https://gist.github.com/nicholasc/e263d976d3aa0304537ea2f075ba7906 | |
*/ | |
class Duotone extends OnPixelBased implements FilterInterface | |
{ | |
/** @var array A matrix of all red duotone values based on a grayscale index. */ | |
protected $redPixels = array(); | |
/** @var array A matrix of all green duotone values based on a grayscale index. */ | |
protected $greenPixels = array(); | |
/** @var array A matrix of all blue duotone values based on a grayscale index. */ | |
protected $bluePixels = array(); | |
/** | |
* Duotone filter class constructor. | |
* | |
* @param \Imagine\Image\Palette\Color\RGB $light The lightest color in the dual tone. | |
* @param \Imagine\Image\Palette\Color\RGB $dark The darkest color in the dual tone. | |
* | |
* @return void | |
*/ | |
public function __construct($light, $dark) | |
{ | |
// Calculate averages between light and dark colors | |
$redAvg = $light->getRed() - $dark->getRed(); | |
$greenAvg = $light->getGreen() - $dark->getGreen(); | |
$blueAvg = $light->getBlue() - $dark->getBlue(); | |
// Create a matrix of all possible duotone colors based on gray values | |
for($i = 0; $i <= 255; $i++) { | |
$grayAvg = $i / 255; | |
$this->redPixels[$i] = $dark->getRed() + $grayAvg * $redAvg; | |
$this->greenPixels[$i] = $dark->getGreen() + $grayAvg * $greenAvg; | |
$this->bluePixels[$i] = $dark->getBlue() + $grayAvg * $blueAvg; | |
} | |
parent::__construct(function(ImageInterface $image, Point $point) { | |
// Retrieve pixel information | |
$color = $image->getColorAt($point); | |
// Get the grayscale value for this pixel | |
$gray = min(255, round(0.299 * $color->getRed() + 0.114 * $color->getBlue() + 0.587 * $color->getGreen())); | |
// Draw the pixels based on the duotone matrix | |
$image->draw()->dot( | |
$point, | |
new RGB( | |
$color->getPalette(), | |
array( | |
$this->redPixels[$gray], | |
$this->greenPixels[$gray], | |
$this->bluePixels[$gray] | |
), | |
100 | |
) | |
); | |
}); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment