/** * {@inheritdoc} */ public function create(BoxInterface $size, ColorInterface $color = null) { $width = $size->getWidth(); $height = $size->getHeight(); $resource = imagecreatetruecolor($width, $height); if (false === $resource) { throw new RuntimeException('Create operation failed'); } $palette = null !== $color ? $color->getPalette() : new RGB(); $color = $color ? $color : $palette->color('fff'); if (!$color instanceof RGBColor) { throw new InvalidArgumentException('GD driver only supports RGB colors'); } $index = imagecolorallocatealpha($resource, $color->getRed(), $color->getGreen(), $color->getBlue(), round(127 * (100 - $color->getAlpha()) / 100)); if (false === $index) { throw new RuntimeException('Unable to allocate color'); } if (false === imagefill($resource, 0, 0, $index)) { throw new RuntimeException('Could not set background color fill'); } if ($color->getAlpha() >= 95) { imagecolortransparent($resource, $index); } return $this->wrap($resource, $palette, new MetadataBag()); }
/** * {@inheritdoc} */ public function create(BoxInterface $size, ColorInterface $color = null) { $width = $size->getWidth(); $height = $size->getHeight(); $palette = null !== $color ? $color->getPalette() : new RGB(); $color = null !== $color ? $color : $palette->color('fff'); try { $gmagick = new \Gmagick(); // Gmagick does not support creation of CMYK GmagickPixel // see https://bugs.php.net/bug.php?id=64466 if ($color instanceof CMYKColor) { $switchPalette = $palette; $palette = new RGB(); $pixel = new \GmagickPixel($palette->color((string) $color)); } else { $switchPalette = null; $pixel = new \GmagickPixel((string) $color); } if ($color->getPalette()->supportsAlpha() && $color->getAlpha() < 100) { throw new NotSupportedException('alpha transparency is not supported'); } $gmagick->newimage($width, $height, $pixel->getcolor(false)); $gmagick->setimagecolorspace(\Gmagick::COLORSPACE_TRANSPARENT); $gmagick->setimagebackgroundcolor($pixel); $image = new Image($gmagick, $palette, new MetadataBag()); if ($switchPalette) { $image->usePalette($switchPalette); } return $image; } catch (\GmagickException $e) { throw new RuntimeException('Could not create empty image', $e->getCode(), $e); } }
/** * {@inheritdoc} * * @return ImageInterface */ public function thumbnail(BoxInterface $size, $mode = ImageInterface::THUMBNAIL_INSET, $filter = ImageInterface::FILTER_UNDEFINED) { if ($mode !== ImageInterface::THUMBNAIL_INSET && $mode !== ImageInterface::THUMBNAIL_OUTBOUND) { throw new InvalidArgumentException('Invalid mode specified'); } $imageSize = $this->getSize(); $ratios = array($size->getWidth() / $imageSize->getWidth(), $size->getHeight() / $imageSize->getHeight()); $thumbnail = $this->copy(); $thumbnail->usePalette($this->palette()); $thumbnail->strip(); // if target width is larger than image width // AND target height is longer than image height if ($size->contains($imageSize)) { return $thumbnail; } if ($mode === ImageInterface::THUMBNAIL_INSET) { $ratio = min($ratios); } else { $ratio = max($ratios); } if ($mode === ImageInterface::THUMBNAIL_OUTBOUND) { if (!$imageSize->contains($size)) { $size = new Box(min($imageSize->getWidth(), $size->getWidth()), min($imageSize->getHeight(), $size->getHeight())); } else { $imageSize = $thumbnail->getSize()->scale($ratio); $thumbnail->resize($imageSize, $filter); } $thumbnail->crop(new Point(max(0, round(($imageSize->getWidth() - $size->getWidth()) / 2)), max(0, round(($imageSize->getHeight() - $size->getHeight()) / 2))), $size); } else { if (!$imageSize->contains($size)) { $imageSize = $imageSize->scale($ratio); $thumbnail->resize($imageSize, $filter); } else { $imageSize = $thumbnail->getSize()->scale($ratio); $thumbnail->resize($imageSize, $filter); } } return $thumbnail; }
/** * {@inheritdoc} */ public function create(BoxInterface $size, ColorInterface $color = null) { $width = $size->getWidth(); $height = $size->getHeight(); $palette = null !== $color ? $color->getPalette() : new RGB(); $color = null !== $color ? $color : $palette->color('fff'); try { $pixel = new \ImagickPixel((string) $color); $pixel->setColorValue(\Imagick::COLOR_ALPHA, $color->getAlpha() / 100); $imagick = new \Imagick(); $imagick->newImage($width, $height, $pixel); $imagick->setImageMatte(true); $imagick->setImageBackgroundColor($pixel); if (version_compare('6.3.1', $this->getVersion($imagick)) < 0) { $imagick->setImageOpacity($pixel->getColorValue(\Imagick::COLOR_ALPHA)); } $pixel->clear(); $pixel->destroy(); return new Image($imagick, $palette, new MetadataBag()); } catch (\ImagickException $e) { throw new RuntimeException('Could not create empty image', $e->getCode(), $e); } }
/** * {@inheritdoc} */ public function contains(BoxInterface $box, PointInterface $start = null) { $start = $start ? $start : new Point(0, 0); return $start->in($this) && $this->width >= $box->getWidth() + $start->getX() && $this->height >= $box->getHeight() + $start->getY(); }
/** * {@inheritdoc} */ public function in(BoxInterface $box) { return $this->getX() < $box->getWidth() && $this->getY() < $box->getHeight(); }
/** * {@inheritdoc} */ public function pieSlice(PointInterface $center, BoxInterface $size, $start, $end, ColorInterface $color, $fill = false, $thickness = 1) { $width = $size->getWidth(); $height = $size->getHeight(); $x1 = round($center->getX() + $width / 2 * cos(deg2rad($start))); $y1 = round($center->getY() + $height / 2 * sin(deg2rad($start))); $x2 = round($center->getX() + $width / 2 * cos(deg2rad($end))); $y2 = round($center->getY() + $height / 2 * sin(deg2rad($end))); if ($fill) { $this->chord($center, $size, $start, $end, $color, true, $thickness); $this->polygon(array($center, new Point($x1, $y1), new Point($x2, $y2)), $color, true, $thickness); } else { $this->arc($center, $size, $start, $end, $color, $thickness); $this->line($center, new Point($x1, $y1), $color, $thickness); $this->line($center, new Point($x2, $y2), $color, $thickness); } return $this; }
/** * Internal * * Generates a GD image * * @param BoxInterface $size * @param string the operation initiating the creation * * @return resource * * @throws RuntimeException * */ private function createImage(BoxInterface $size, $operation) { $resource = imagecreatetruecolor($size->getWidth(), $size->getHeight()); if (false === $resource) { throw new RuntimeException('Image ' . $operation . ' failed'); } if (false === imagealphablending($resource, false) || false === imagesavealpha($resource, true)) { throw new RuntimeException('Image ' . $operation . ' failed'); } if (function_exists('imageantialias')) { imageantialias($resource, true); } $transparent = imagecolorallocatealpha($resource, 255, 255, 255, 127); imagefill($resource, 0, 0, $transparent); imagecolortransparent($resource, $transparent); return $resource; }
/** * {@inheritdoc} */ public function pieSlice(PointInterface $center, BoxInterface $size, $start, $end, ColorInterface $color, $fill = false, $thickness = 1) { imagesetthickness($this->resource, max(1, (int) $thickness)); if ($fill) { $style = IMG_ARC_EDGED; } else { $style = IMG_ARC_EDGED | IMG_ARC_NOFILL; } if (false === imagealphablending($this->resource, true)) { throw new RuntimeException('Draw chord operation failed'); } if (false === imagefilledarc($this->resource, $center->getX(), $center->getY(), $size->getWidth(), $size->getHeight(), $start, $end, $this->getColor($color), $style)) { imagealphablending($this->resource, false); throw new RuntimeException('Draw chord operation failed'); } if (false === imagealphablending($this->resource, false)) { throw new RuntimeException('Draw chord operation failed'); } return $this; }
/** * {@inheritdoc} * * @return ImageInterface */ public function resize(BoxInterface $size, $filter = ImageInterface::FILTER_UNDEFINED) { static $supportedFilters = array(ImageInterface::FILTER_UNDEFINED => \Gmagick::FILTER_UNDEFINED, ImageInterface::FILTER_BESSEL => \Gmagick::FILTER_BESSEL, ImageInterface::FILTER_BLACKMAN => \Gmagick::FILTER_BLACKMAN, ImageInterface::FILTER_BOX => \Gmagick::FILTER_BOX, ImageInterface::FILTER_CATROM => \Gmagick::FILTER_CATROM, ImageInterface::FILTER_CUBIC => \Gmagick::FILTER_CUBIC, ImageInterface::FILTER_GAUSSIAN => \Gmagick::FILTER_GAUSSIAN, ImageInterface::FILTER_HANNING => \Gmagick::FILTER_HANNING, ImageInterface::FILTER_HAMMING => \Gmagick::FILTER_HAMMING, ImageInterface::FILTER_HERMITE => \Gmagick::FILTER_HERMITE, ImageInterface::FILTER_LANCZOS => \Gmagick::FILTER_LANCZOS, ImageInterface::FILTER_MITCHELL => \Gmagick::FILTER_MITCHELL, ImageInterface::FILTER_POINT => \Gmagick::FILTER_POINT, ImageInterface::FILTER_QUADRATIC => \Gmagick::FILTER_QUADRATIC, ImageInterface::FILTER_SINC => \Gmagick::FILTER_SINC, ImageInterface::FILTER_TRIANGLE => \Gmagick::FILTER_TRIANGLE); if (!array_key_exists($filter, $supportedFilters)) { throw new InvalidArgumentException('Unsupported filter type'); } try { $this->gmagick->resizeimage($size->getWidth(), $size->getHeight(), $supportedFilters[$filter], 1); } catch (\GmagickException $e) { throw new RuntimeException('Resize operation failed', $e->getCode(), $e); } return $this; }
/** * {@inheritdoc} * * @return ImageInterface */ public function resize(BoxInterface $size, $filter = ImageInterface::FILTER_UNDEFINED) { try { $this->imagick->resizeImage($size->getWidth(), $size->getHeight(), $this->getFilter($filter), 1); } catch (\ImagickException $e) { throw new RuntimeException('Resize operation failed', $e->getCode(), $e); } return $this; }