vendor/imagine/imagine/src/Imagick/Imagine.php line 140

Open in your IDE?
  1. <?php
  2. /*
  3.  * This file is part of the Imagine package.
  4.  *
  5.  * (c) Bulat Shakirzyanov <mallluhuct@gmail.com>
  6.  *
  7.  * For the full copyright and license information, please view the LICENSE
  8.  * file that was distributed with this source code.
  9.  */
  10. namespace Imagine\Imagick;
  11. use Imagine\Exception\InvalidArgumentException;
  12. use Imagine\Exception\NotSupportedException;
  13. use Imagine\Exception\RuntimeException;
  14. use Imagine\Factory\ClassFactoryInterface;
  15. use Imagine\File\LoaderInterface;
  16. use Imagine\Image\AbstractImagine;
  17. use Imagine\Image\BoxInterface;
  18. use Imagine\Image\Metadata\MetadataBag;
  19. use Imagine\Image\Palette\CMYK;
  20. use Imagine\Image\Palette\Color\ColorInterface;
  21. use Imagine\Image\Palette\Grayscale;
  22. use Imagine\Image\Palette\RGB;
  23. use Imagine\Utils\ErrorHandling;
  24. /**
  25.  * Imagine implementation using the Imagick PHP extension.
  26.  */
  27. final class Imagine extends AbstractImagine
  28. {
  29.     /**
  30.      * @throws \Imagine\Exception\RuntimeException
  31.      */
  32.     public function __construct()
  33.     {
  34.         if (!class_exists('Imagick')) {
  35.             throw new RuntimeException('Imagick not installed');
  36.         }
  37.         $version $this->getVersion(new \Imagick());
  38.         if (version_compare('6.2.9'$version) > 0) {
  39.             throw new RuntimeException(sprintf('ImageMagick version 6.2.9 or higher is required, %s provided'$version));
  40.         }
  41.         if ($version === '7.0.7-32') { // https://github.com/avalanche123/Imagine/issues/689
  42.             throw new RuntimeException(sprintf('ImageMagick version %s has known bugs that prevent it from working'$version));
  43.         }
  44.     }
  45.     /**
  46.      * {@inheritdoc}
  47.      *
  48.      * @see \Imagine\Image\ImagineInterface::open()
  49.      */
  50.     public function open($path)
  51.     {
  52.         $loader $path instanceof LoaderInterface $path $this->getClassFactory()->createFileLoader($path);
  53.         $path $loader->getPath();
  54.         try {
  55.             if ($loader->isLocalFile()) {
  56.                 if (DIRECTORY_SEPARATOR === '\\' && PHP_INT_SIZE === && PHP_VERSION_ID >= 70100 && PHP_VERSION_ID 70200) {
  57.                     $imagick = new \Imagick();
  58.                     // PHP 7.1 64 bit on Windows: don't pass the file name to the constructor: it may break PHP - see https://github.com/mkoppanen/imagick/issues/252
  59.                     $imagick->readImageBlob($loader->getData(), $path);
  60.                 } else {
  61.                     $imagick = new \Imagick($loader->getPath());
  62.                 }
  63.             } else {
  64.                 $imagick = new \Imagick();
  65.                 $imagick->readImageBlob($loader->getData());
  66.             }
  67.             $image $this->getClassFactory()->createImage(ClassFactoryInterface::HANDLE_IMAGICK$imagick$this->createPalette($imagick), $this->getMetadataReader()->readFile($loader));
  68.         } catch (\ImagickException $e) {
  69.             throw new RuntimeException(sprintf('Unable to open image %s'$path), $e->getCode(), $e);
  70.         }
  71.         return $image;
  72.     }
  73.     /**
  74.      * {@inheritdoc}
  75.      *
  76.      * @see \Imagine\Image\ImagineInterface::create()
  77.      */
  78.     public function create(BoxInterface $sizeColorInterface $color null)
  79.     {
  80.         $width $size->getWidth();
  81.         $height $size->getHeight();
  82.         $palette null !== $color $color->getPalette() : new RGB();
  83.         $color null !== $color $color $palette->color('fff');
  84.         try {
  85.             $pixel = new \ImagickPixel((string) $color);
  86.             $pixel->setColorValue(\Imagick::COLOR_ALPHA$color->getAlpha() / 100);
  87.             $imagick = new \Imagick();
  88.             $imagick->newImage($width$height$pixel);
  89.             $imagick->setImageMatte(true);
  90.             $imagick->setImageBackgroundColor($pixel);
  91.             if (version_compare('6.3.1'$this->getVersion($imagick)) < 0) {
  92.                 // setImageOpacity was replaced with setImageAlpha in php-imagick v3.4.3
  93.                 if (method_exists($imagick'setImageAlpha')) {
  94.                     $imagick->setImageAlpha($pixel->getColorValue(\Imagick::COLOR_ALPHA));
  95.                 } else {
  96.                     ErrorHandling::ignoring(E_DEPRECATED, function () use ($imagick$pixel) {
  97.                         $imagick->setImageOpacity($pixel->getColorValue(\Imagick::COLOR_ALPHA));
  98.                     });
  99.                 }
  100.             }
  101.             $pixel->clear();
  102.             $pixel->destroy();
  103.             return $this->getClassFactory()->createImage(ClassFactoryInterface::HANDLE_IMAGICK$imagick$palette, new MetadataBag());
  104.         } catch (\ImagickException $e) {
  105.             throw new RuntimeException('Could not create empty image'$e->getCode(), $e);
  106.         }
  107.     }
  108.     /**
  109.      * {@inheritdoc}
  110.      *
  111.      * @see \Imagine\Image\ImagineInterface::load()
  112.      */
  113.     public function load($string)
  114.     {
  115.         try {
  116.             $imagick = new \Imagick();
  117.             $imagick->readImageBlob($string);
  118.             $imagick->setImageMatte(true);
  119.             return $this->getClassFactory()->createImage(ClassFactoryInterface::HANDLE_IMAGICK$imagick$this->createPalette($imagick), $this->getMetadataReader()->readData($string));
  120.         } catch (\ImagickException $e) {
  121.             throw new RuntimeException('Could not load image from string'$e->getCode(), $e);
  122.         }
  123.     }
  124.     /**
  125.      * {@inheritdoc}
  126.      *
  127.      * @see \Imagine\Image\ImagineInterface::read()
  128.      */
  129.     public function read($resource)
  130.     {
  131.         if (!is_resource($resource)) {
  132.             throw new InvalidArgumentException('Variable does not contain a stream resource');
  133.         }
  134.         $content stream_get_contents($resource);
  135.         try {
  136.             $imagick = new \Imagick();
  137.             $imagick->readImageBlob($content);
  138.         } catch (\ImagickException $e) {
  139.             throw new RuntimeException('Could not read image from resource'$e->getCode(), $e);
  140.         }
  141.         return $this->getClassFactory()->createImage(ClassFactoryInterface::HANDLE_IMAGICK$imagick$this->createPalette($imagick), $this->getMetadataReader()->readData($content$resource));
  142.     }
  143.     /**
  144.      * {@inheritdoc}
  145.      *
  146.      * @see \Imagine\Image\ImagineInterface::font()
  147.      */
  148.     public function font($file$sizeColorInterface $color)
  149.     {
  150.         return $this->getClassFactory()->createFont(ClassFactoryInterface::HANDLE_IMAGICK$file$size$color);
  151.     }
  152.     /**
  153.      * Returns the palette corresponding to an \Imagick resource colorspace.
  154.      *
  155.      * @param \Imagick $imagick
  156.      *
  157.      * @throws \Imagine\Exception\NotSupportedException
  158.      *
  159.      * @return \Imagine\Image\Palette\CMYK|\Imagine\Image\Palette\Grayscale|\Imagine\Image\Palette\RGB
  160.      */
  161.     private function createPalette(\Imagick $imagick)
  162.     {
  163.         switch ($imagick->getImageColorspace()) {
  164.             case \Imagick::COLORSPACE_RGB:
  165.             case \Imagick::COLORSPACE_SRGB:
  166.                 return new RGB();
  167.             case \Imagick::COLORSPACE_CMYK:
  168.                 return new CMYK();
  169.             case \Imagick::COLORSPACE_GRAY:
  170.                 return new Grayscale();
  171.             default:
  172.                 throw new NotSupportedException('Only RGB and CMYK colorspace are currently supported');
  173.         }
  174.     }
  175.     /**
  176.      * Returns ImageMagick version.
  177.      *
  178.      * @param \Imagick $imagick
  179.      *
  180.      * @return string
  181.      */
  182.     private function getVersion(\Imagick $imagick)
  183.     {
  184.         $v $imagick->getVersion();
  185.         list($version) = sscanf($v['versionString'], 'ImageMagick %s %04d-%02d-%02d %s %s');
  186.         return $version;
  187.     }
  188. }