"Fossies" - the Fresh Open Source Software Archive

Member "grav/vendor/gregwar/image/Gregwar/Image/Adapter/GD.php" (1 Sep 2020, 17757 Bytes) of package /linux/www/grav-v1.6.27.zip:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) PHP source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "GD.php" see the Fossies "Dox" file reference documentation.

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