Skip to content

Instantly share code, notes, and snippets.

@nicholasc
Last active January 4, 2022 07:05
Show Gist options
  • Save nicholasc/e263d976d3aa0304537ea2f075ba7906 to your computer and use it in GitHub Desktop.
Save nicholasc/e263d976d3aa0304537ea2f075ba7906 to your computer and use it in GitHub Desktop.
A Duotone filter for Imagine PHP library.
<?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