vendor/gregwar/image/Gregwar/Image/Adapter/GD.php line 90

Open in your IDE?
  1. <?php
  2. namespace Gregwar\Image\Adapter;
  3. use Gregwar\Image\Image;
  4. use Gregwar\Image\ImageColor;
  5. class GD extends Common
  6. {
  7.     public static $gdTypes = array(
  8.         'jpeg'  => \IMG_JPG,
  9.         'gif'   => \IMG_GIF,
  10.         'png'   => \IMG_PNG,
  11.         'webp'  => \IMG_WEBP
  12.     );
  13.     protected function loadResource($resource)
  14.     {
  15.         parent::loadResource($resource);
  16.         imagesavealpha($this->resourcetrue);
  17.     }
  18.     /**
  19.      * Gets the width and the height for writing some text.
  20.      */
  21.     public static function TTFBox($font$text$size$angle 0)
  22.     {
  23.         $box imagettfbbox($size$angle$font$text);
  24.         return array(
  25.             'width'  => abs($box[2] - $box[0]),
  26.             'height' => abs($box[3] - $box[5]),
  27.         );
  28.     }
  29.     public function __construct()
  30.     {
  31.         parent::__construct();
  32.         if (!(extension_loaded('gd') && function_exists('gd_info'))) {
  33.             throw new \RuntimeException('You need to install GD PHP Extension to use this library');
  34.         }
  35.     }
  36.     /**
  37.      * {@inheritdoc}
  38.      */
  39.     public function getName()
  40.     {
  41.         return 'GD';
  42.     }
  43.     /**
  44.      * {@inheritdoc}
  45.      */
  46.     public function fillBackground($background 0xffffff)
  47.     {
  48.         $w $this->width();
  49.         $h $this->height();
  50.         $n imagecreatetruecolor($w$h);
  51.         imagefill($n00ImageColor::gdAllocate($this->resource$background));
  52.         imagecopyresampled($n$this->resource0000$w$h$w$h);
  53.         imagedestroy($this->resource);
  54.         $this->resource $n;
  55.         return $this;
  56.     }
  57.     /**
  58.      * Do the image resize.
  59.      *
  60.      * @return $this
  61.      */
  62.     protected function doResize($bg$target_width$target_height$new_width$new_height)
  63.     {
  64.         $width $this->width();
  65.         $height $this->height();
  66.         $n imagecreatetruecolor($target_width$target_height);
  67.         if ($bg != 'transparent') {
  68.             imagefill($n00ImageColor::gdAllocate($this->resource$bg));
  69.         } else {
  70.             imagealphablending($nfalse);
  71.             $color ImageColor::gdAllocate($this->resource'transparent');
  72.             imagefill($n00$color);
  73.             imagesavealpha($ntrue);
  74.         }
  75.         imagecopyresampled($n$this->resource, ($target_width $new_width) / 2, ($target_height $new_height) / 200$new_width$new_height$width$height);
  76.         imagedestroy($this->resource);
  77.         $this->resource $n;
  78.         return $this;
  79.     }
  80.     /**
  81.      * {@inheritdoc}
  82.      */
  83.     public function crop($x$y$width$height)
  84.     {
  85.         $destination imagecreatetruecolor($width$height);
  86.         imagealphablending($destinationfalse);
  87.         imagesavealpha($destinationtrue);
  88.         imagecopy($destination$this->resource00$x$y$this->width(), $this->height());
  89.         imagedestroy($this->resource);
  90.         $this->resource $destination;
  91.         return $this;
  92.     }
  93.     /**
  94.      * {@inheritdoc}
  95.      */
  96.     public function negate()
  97.     {
  98.         imagefilter($this->resourceIMG_FILTER_NEGATE);
  99.         return $this;
  100.     }
  101.     /**
  102.      * {@inheritdoc}
  103.      */
  104.     public function brightness($brightness)
  105.     {
  106.         imagefilter($this->resourceIMG_FILTER_BRIGHTNESS$brightness);
  107.         return $this;
  108.     }
  109.     /**
  110.      * {@inheritdoc}
  111.      */
  112.     public function contrast($contrast)
  113.     {
  114.         imagefilter($this->resourceIMG_FILTER_CONTRAST$contrast);
  115.         return $this;
  116.     }
  117.     /**
  118.      * {@inheritdoc}
  119.      */
  120.     public function grayscale()
  121.     {
  122.         imagefilter($this->resourceIMG_FILTER_GRAYSCALE);
  123.         return $this;
  124.     }
  125.     /**
  126.      * {@inheritdoc}
  127.      */
  128.     public function emboss()
  129.     {
  130.         imagefilter($this->resourceIMG_FILTER_EMBOSS);
  131.         return $this;
  132.     }
  133.     /**
  134.      * {@inheritdoc}
  135.      */
  136.     public function smooth($p)
  137.     {
  138.         imagefilter($this->resourceIMG_FILTER_SMOOTH$p);
  139.         return $this;
  140.     }
  141.     /**
  142.      * {@inheritdoc}
  143.      */
  144.     public function sharp()
  145.     {
  146.         imagefilter($this->resourceIMG_FILTER_MEAN_REMOVAL);
  147.         return $this;
  148.     }
  149.     /**
  150.      * {@inheritdoc}
  151.      */
  152.     public function edge()
  153.     {
  154.         imagefilter($this->resourceIMG_FILTER_EDGEDETECT);
  155.         return $this;
  156.     }
  157.     /**
  158.      * {@inheritdoc}
  159.      */
  160.     public function colorize($red$green$blue)
  161.     {
  162.         imagefilter($this->resourceIMG_FILTER_COLORIZE$red$green$blue);
  163.         return $this;
  164.     }
  165.     /**
  166.      * {@inheritdoc}
  167.      */
  168.     public function sepia()
  169.     {
  170.         imagefilter($this->resourceIMG_FILTER_GRAYSCALE);
  171.         imagefilter($this->resourceIMG_FILTER_COLORIZE100500);
  172.         return $this;
  173.     }
  174.     /**
  175.      * {@inheritdoc}
  176.      */
  177.     public function gaussianBlur($blurFactor 1)
  178.     {
  179.         $blurFactor round($blurFactor); // blurFactor has to be an integer
  180.         $originalWidth $this->width();
  181.         $originalHeight $this->height();
  182.         $smallestWidth ceil($originalWidth pow(0.5$blurFactor));
  183.         $smallestHeight ceil($originalHeight pow(0.5$blurFactor));
  184.         // for the first run, the previous image is the original input
  185.         $prevImage $this->resource;
  186.         $prevWidth $originalWidth;
  187.         $prevHeight $originalHeight;
  188.         // scale way down and gradually scale back up, blurring all the way
  189.         for ($i 0$i $blurFactor; ++$i) {
  190.             // determine dimensions of next image
  191.             $nextWidth $smallestWidth pow(2$i);
  192.             $nextHeight $smallestHeight pow(2$i);
  193.             // resize previous image to next size
  194.             $nextImage imagecreatetruecolor($nextWidth$nextHeight);
  195.             imagecopyresized($nextImage$prevImage0000,
  196.                 $nextWidth$nextHeight$prevWidth$prevHeight);
  197.             // apply blur filter
  198.             imagefilter($nextImageIMG_FILTER_GAUSSIAN_BLUR);
  199.             // now the new image becomes the previous image for the next step
  200.             $prevImage $nextImage;
  201.             $prevWidth $nextWidth;
  202.             $prevHeight $nextHeight;
  203.         }
  204.         // scale back to original size and blur one more time
  205.         imagecopyresized($this->resource$nextImage,
  206.             0000$originalWidth$originalHeight$nextWidth$nextHeight);
  207.         imagefilter($this->resourceIMG_FILTER_GAUSSIAN_BLUR);
  208.         // clean up
  209.         imagedestroy($prevImage);
  210.         return $this;
  211.     }
  212.     /**
  213.      * {@inheritdoc}
  214.      */
  215.     public function merge(Image $other$x 0$y 0$width null$height null)
  216.     {
  217.         $other = clone $other;
  218.         $other->init();
  219.         $other->applyOperations();
  220.         imagealphablending($this->resourcetrue);
  221.         if (null == $width) {
  222.             $width $other->width();
  223.         }
  224.         if (null == $height) {
  225.             $height $other->height();
  226.         }
  227.         imagecopyresampled($this->resource$other->getAdapter()->getResource(), $x$y00$width$height$width$height);
  228.         return $this;
  229.     }
  230.     /**
  231.      * {@inheritdoc}
  232.      */
  233.     public function rotate($angle$background 0xffffff)
  234.     {
  235.         $this->resource imagerotate($this->resource$angleImageColor::gdAllocate($this->resource$background));
  236.         imagealphablending($this->resourcetrue);
  237.         imagesavealpha($this->resourcetrue);
  238.         return $this;
  239.     }
  240.     /**
  241.      * {@inheritdoc}
  242.      */
  243.     public function fill($color 0xffffff$x 0$y 0)
  244.     {
  245.         imagealphablending($this->resourcefalse);
  246.         imagefill($this->resource$x$yImageColor::gdAllocate($this->resource$color));
  247.         return $this;
  248.     }
  249.     /**
  250.      * {@inheritdoc}
  251.      */
  252.     public function write($font$text$x 0$y 0$size 12$angle 0$color 0x000000$align 'left')
  253.     {
  254.         imagealphablending($this->resourcetrue);
  255.         if ($align != 'left') {
  256.             $sim_size self::TTFBox($font$text$size$angle);
  257.             if ($align == 'center') {
  258.                 $x -= $sim_size['width'] / 2;
  259.             }
  260.             if ($align == 'right') {
  261.                 $x -= $sim_size['width'];
  262.             }
  263.         }
  264.         imagettftext($this->resource$size$angle$x$yImageColor::gdAllocate($this->resource$color), $font$text);
  265.         return $this;
  266.     }
  267.     /**
  268.      * {@inheritdoc}
  269.      */
  270.     public function rectangle($x1$y1$x2$y2$color$filled false)
  271.     {
  272.         if ($filled) {
  273.             imagefilledrectangle($this->resource$x1$y1$x2$y2ImageColor::gdAllocate($this->resource$color));
  274.         } else {
  275.             imagerectangle($this->resource$x1$y1$x2$y2ImageColor::gdAllocate($this->resource$color));
  276.         }
  277.         return $this;
  278.     }
  279.     /**
  280.      * {@inheritdoc}
  281.      */
  282.     public function roundedRectangle($x1$y1$x2$y2$radius$color$filled false)
  283.     {
  284.         if ($color) {
  285.             $color ImageColor::gdAllocate($this->resource$color);
  286.         }
  287.         if ($filled == true) {
  288.             imagefilledrectangle($this->resource$x1 $radius$y1$x2 $radius$y2$color);
  289.             imagefilledrectangle($this->resource$x1$y1 $radius$x1 $radius 1$y2 $radius$color);
  290.             imagefilledrectangle($this->resource$x2 $radius 1$y1 $radius$x2$y2 $radius$color);
  291.             imagefilledarc($this->resource$x1 $radius$y1 $radius$radius 2$radius 2180270$colorIMG_ARC_PIE);
  292.             imagefilledarc($this->resource$x2 $radius$y1 $radius$radius 2$radius 2270360$colorIMG_ARC_PIE);
  293.             imagefilledarc($this->resource$x1 $radius$y2 $radius$radius 2$radius 290180$colorIMG_ARC_PIE);
  294.             imagefilledarc($this->resource$x2 $radius$y2 $radius$radius 2$radius 236090$colorIMG_ARC_PIE);
  295.         } else {
  296.             imageline($this->resource$x1 $radius$y1$x2 $radius$y1$color);
  297.             imageline($this->resource$x1 $radius$y2$x2 $radius$y2$color);
  298.             imageline($this->resource$x1$y1 $radius$x1$y2 $radius$color);
  299.             imageline($this->resource$x2$y1 $radius$x2$y2 $radius$color);
  300.             imagearc($this->resource$x1 $radius$y1 $radius$radius 2$radius 2180270$color);
  301.             imagearc($this->resource$x2 $radius$y1 $radius$radius 2$radius 2270360$color);
  302.             imagearc($this->resource$x1 $radius$y2 $radius$radius 2$radius 290180$color);
  303.             imagearc($this->resource$x2 $radius$y2 $radius$radius 2$radius 236090$color);
  304.         }
  305.         return $this;
  306.     }
  307.     /**
  308.      * {@inheritdoc}
  309.      */
  310.     public function line($x1$y1$x2$y2$color 0x000000)
  311.     {
  312.         imageline($this->resource$x1$y1$x2$y2ImageColor::gdAllocate($this->resource$color));
  313.         return $this;
  314.     }
  315.     /**
  316.      * {@inheritdoc}
  317.      */
  318.     public function ellipse($cx$cy$width$height$color 0x000000$filled false)
  319.     {
  320.         if ($filled) {
  321.             imagefilledellipse($this->resource$cx$cy$width$heightImageColor::gdAllocate($this->resource$color));
  322.         } else {
  323.             imageellipse($this->resource$cx$cy$width$heightImageColor::gdAllocate($this->resource$color));
  324.         }
  325.         return $this;
  326.     }
  327.     /**
  328.      * {@inheritdoc}
  329.      */
  330.     public function circle($cx$cy$r$color 0x000000$filled false)
  331.     {
  332.         return $this->ellipse($cx$cy$r$rImageColor::gdAllocate($this->resource$color), $filled);
  333.     }
  334.     /**
  335.      * {@inheritdoc}
  336.      */
  337.     public function polygon(array $points$color$filled false)
  338.     {
  339.         if ($filled) {
  340.             imagefilledpolygon($this->resource$pointscount($points) / 2ImageColor::gdAllocate($this->resource$color));
  341.         } else {
  342.             imagepolygon($this->resource$pointscount($points) / 2ImageColor::gdAllocate($this->resource$color));
  343.         }
  344.         return $this;
  345.     }
  346.     /**
  347.      *  {@inheritdoc}
  348.      */
  349.     public function flip($flipVertical$flipHorizontal)
  350.     {
  351.         if (!$flipVertical && !$flipHorizontal) {
  352.             return $this;
  353.         }
  354.         if (function_exists('imageflip')) {
  355.             if ($flipVertical && $flipHorizontal) {
  356.                 $flipMode \IMG_FLIP_BOTH;
  357.             } elseif ($flipVertical && !$flipHorizontal) {
  358.                 $flipMode \IMG_FLIP_VERTICAL;
  359.             } elseif (!$flipVertical && $flipHorizontal) {
  360.                 $flipMode \IMG_FLIP_HORIZONTAL;
  361.             }
  362.             imageflip($this->resource$flipMode);
  363.         } else {
  364.             $width $this->width();
  365.             $height $this->height();
  366.             $src_x      0;
  367.             $src_y      0;
  368.             $src_width  $width;
  369.             $src_height $height;
  370.             if ($flipVertical) {
  371.                 $src_y      $height 1;
  372.                 $src_height = -$height;
  373.             }
  374.             if ($flipHorizontal) {
  375.                 $src_x      $width 1;
  376.                 $src_width  = -$width;
  377.             }
  378.             $imgdest imagecreatetruecolor($width$height);
  379.             imagealphablending($imgdestfalse);
  380.             imagesavealpha($imgdesttrue);
  381.             if (imagecopyresampled($imgdest$this->resource00$src_x$src_y$width$height$src_width$src_height)) {
  382.                 imagedestroy($this->resource);
  383.                 $this->resource $imgdest;
  384.             }
  385.         }
  386.         return $this;
  387.     }
  388.     /**
  389.      * {@inheritdoc}
  390.      */
  391.     public function width()
  392.     {
  393.         if (null === $this->resource) {
  394.             $this->init();
  395.         }
  396.         return imagesx($this->resource);
  397.     }
  398.     /**
  399.      * {@inheritdoc}
  400.      */
  401.     public function height()
  402.     {
  403.         if (null === $this->resource) {
  404.             $this->init();
  405.         }
  406.         return imagesy($this->resource);
  407.     }
  408.     protected function createImage($width$height)
  409.     {
  410.         $this->resource imagecreatetruecolor($width$height);
  411.     }
  412.     protected function createImageFromData($data)
  413.     {
  414.         $this->resource = @imagecreatefromstring($data);
  415.     }
  416.     /**
  417.      * Converts the image to true color.
  418.      */
  419.     protected function convertToTrueColor()
  420.     {
  421.         if (!imageistruecolor($this->resource)) {
  422.             if (function_exists('imagepalettetotruecolor')) {
  423.                 // Available in PHP 5.5
  424.                 imagepalettetotruecolor($this->resource);
  425.             } else {
  426.                 $transparentIndex imagecolortransparent($this->resource);
  427.                 $w $this->width();
  428.                 $h $this->height();
  429.                 $img imagecreatetruecolor($w$h);
  430.                 imagecopy($img$this->resource0000$w$h);
  431.                 if ($transparentIndex != -1) {
  432.                     $width $this->width();
  433.                     $height $this->height();
  434.                     imagealphablending($imgfalse);
  435.                     imagesavealpha($imgtrue);
  436.                     for ($x 0$x $width; ++$x) {
  437.                         for ($y 0$y $height; ++$y) {
  438.                             if (imagecolorat($this->resource$x$y) == $transparentIndex) {
  439.                                 imagesetpixel($img$x$y127 << 24);
  440.                             }
  441.                         }
  442.                     }
  443.                 }
  444.                 $this->resource $img;
  445.             }
  446.         }
  447.         imagesavealpha($this->resourcetrue);
  448.     }
  449.     /**
  450.      * {@inheritdoc}
  451.      */
  452.     public function saveGif($file)
  453.     {
  454.         $transColor imagecolorallocatealpha($this->resource255255255127);
  455.         imagecolortransparent($this->resource$transColor);
  456.         imagegif($this->resource$file);
  457.         return $this;
  458.     }
  459.     /**
  460.      * {@inheritdoc}
  461.      */
  462.     public function savePng($file)
  463.     {
  464.         imagepng($this->resource$file);
  465.         return $this;
  466.     }
  467.     
  468.     /**
  469.      * {@inheritdoc}
  470.      */
  471.     public function saveWebp($file$quality)
  472.     {
  473.         imagewebp($this->resource$file$quality);
  474.         return $this;
  475.     }
  476.     /**
  477.      * {@inheritdoc}
  478.      */
  479.     public function saveJpeg($file$quality)
  480.     {
  481.         imagejpeg($this->resource$file$quality);
  482.         return $this;
  483.     }
  484.     /**
  485.      * Try to open the file using jpeg.
  486.      */
  487.     protected function openJpeg($file)
  488.     {
  489.         if (file_exists($file) && filesize($file)) {
  490.             $this->resource = @imagecreatefromjpeg($file);
  491.         } else {
  492.             $this->resource false;
  493.         }
  494.     }
  495.     /**
  496.      * Try to open the file using gif.
  497.      */
  498.     protected function openGif($file)
  499.     {
  500.         if (file_exists($file) && filesize($file)) {
  501.             $this->resource = @imagecreatefromgif($file);
  502.         } else {
  503.             $this->resource false;
  504.         }
  505.     }
  506.     /**
  507.      * Try to open the file using PNG.
  508.      */
  509.     protected function openPng($file)
  510.     {
  511.         if (file_exists($file) && filesize($file)) {
  512.             $this->resource = @imagecreatefrompng($file);
  513.         } else {
  514.             $this->resource false;
  515.         }
  516.     }
  517.     /**
  518.      * Try to open the file using WEBP.
  519.      */
  520.     protected function openWebp($file)
  521.     {
  522.         if (file_exists($file) && filesize($file)) {
  523.             $this->resource = @imagecreatefromwebp($file);
  524.         } else {
  525.             $this->resource false;
  526.         }
  527.     }
  528.     /**
  529.      * Does this adapter supports type ?
  530.      */
  531.     protected function supports($type)
  532.     {
  533.         return imagetypes() & self::$gdTypes[$type];
  534.     }
  535.     protected function getColor($x$y)
  536.     {
  537.         return imagecolorat($this->resource$x$y);
  538.     }
  539.     /**
  540.      * {@inheritdoc}
  541.      */
  542.     public function enableProgressive()
  543.     {
  544.         imageinterlace($this->resource1);
  545.         return $this;
  546.     }
  547. }