/** * Applies scheduled transformation to ImageInterface instance * Returns processed ImageInterface instance * * @param \Imagine\Image\ImageInterface $image * * @return \Imagine\Image\ImageInterface */ function apply(ImageInterface $image) { // We reduce the usage of methods on the image to dramatically increase the performance of this algorithm. // Really... We need that performance... // Therefore we first build a matrix, that holds the colors of the image. $width = $image->getSize()->getWidth(); $height = $image->getSize()->getHeight(); $byteData = new Matrix($width, $height); for ($x = 0; $x < $width; $x++) { for ($y = 0; $y < $height; $y++) { $byteData->setElementAt($x, $y, $image->getColorAt(new Point($x, $y))); } } $dHeight = (int) floor(($this->matrix->getHeight() - 1) / 2); $dWidth = (int) floor(($this->matrix->getWidth() - 1) / 2); for ($y = $dHeight; $y < $height - $dHeight; $y++) { for ($x = $dWidth; $x < $width - $dWidth; $x++) { $sumRed = 0; $sumGreen = 0; $sumBlue = 0; // calculate new color for ($boxX = $x - $dWidth, $matrixX = 0; $boxX <= $x + $dWidth; $boxX++, $matrixX++) { for ($boxY = $y - $dHeight, $matrixY = 0; $boxY <= $y + $dHeight; $boxY++, $matrixY++) { $sumRed = $sumRed + $this->matrix->getElementAt($matrixX, $matrixY) * $byteData->getElementAt($boxX, $boxY)->getRed(); $sumGreen = $sumGreen + $this->matrix->getElementAt($matrixX, $matrixY) * $byteData->getElementAt($boxX, $boxY)->getGreen(); $sumBlue = $sumBlue + $this->matrix->getElementAt($matrixX, $matrixY) * $byteData->getElementAt($boxX, $boxY)->getBlue(); } } // set new color - has to be between 0 and 255! $image->draw()->dot(new Point($x, $y), new Color(array('red' => max(0, min(255, $sumRed)), 'green' => max(0, min(255, $sumGreen)), 'blue' => max(0, min(255, $sumBlue))))); } } return $image; }
/** * @see Liip\ImagineBundle\Imagine\Filter\Loader\LoaderInterface::load() */ public function load(ImageInterface $image, array $options = array()) { $size = $image->getSize(); $width = $size->getWidth(); $height = $size->getHeight(); $alpha = $options['opacity']; for ($x = 0; $x < $width; $x++) { for ($y = 0; $y < $height; $y++) { $point = new Point($x, $y); $color = $image->getColorAt($point); $dR = $color->getRed(); $dG = $color->getGreen(); $dB = $color->getBlue(); $image->draw()->dot($point, new Color(array($dR, $dG, $dB), $alpha)); } } return $image; }
/** * {@inheritdoc} */ public function applyMask(ImageInterface $mask) { if (!$mask instanceof self) { throw new InvalidArgumentException('Cannot mask non-gd images'); } $size = $this->getSize(); $maskSize = $mask->getSize(); if ($size != $maskSize) { throw new InvalidArgumentException(sprintf('The given mask doesn\'t match current image\'s size, Current ' . 'mask\'s dimensions are %s, while image\'s dimensions are %s', $maskSize, $size)); } for ($x = 0, $width = $size->getWidth(); $x < $width; $x++) { for ($y = 0, $height = $size->getHeight(); $y < $height; $y++) { $position = new Point($x, $y); $color = $this->getColorAt($position); $maskColor = $mask->getColorAt($position); $round = (int) round(max($color->getAlpha(), (100 - $color->getAlpha()) * $maskColor->getRed() / 255)); if (false === imagesetpixel($this->resource, $x, $y, $this->getColor($color->dissolve($round - $color->getAlpha())))) { throw new RuntimeException('Apply mask operation failed'); } } } return $this; }