123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630 |
- <?php
- namespace Gregwar\Image\Adapter;
- use Gregwar\Image\Image;
- use Gregwar\Image\ImageColor;
- class GD extends Common
- {
- public static $gdTypes = array(
- 'jpeg' => \IMG_JPG,
- 'gif' => \IMG_GIF,
- 'png' => \IMG_PNG,
- );
- protected function loadResource($resource)
- {
- parent::loadResource($resource);
- imagesavealpha($this->resource, true);
- }
- /**
- * Gets the width and the height for writing some text.
- */
- public static function TTFBox($font, $text, $size, $angle = 0)
- {
- $box = imagettfbbox($size, $angle, $font, $text);
- return array(
- 'width' => abs($box[2] - $box[0]),
- 'height' => abs($box[3] - $box[5]),
- );
- }
- public function __construct()
- {
- parent::__construct();
- if (!(extension_loaded('gd') && function_exists('gd_info'))) {
- throw new \RuntimeException('You need to install GD PHP Extension to use this library');
- }
- }
- /**
- * {@inheritdoc}
- */
- public function getName()
- {
- return 'GD';
- }
- /**
- * {@inheritdoc}
- */
- public function fillBackground($background = 0xffffff)
- {
- $w = $this->width();
- $h = $this->height();
- $n = imagecreatetruecolor($w, $h);
- imagefill($n, 0, 0, ImageColor::gdAllocate($this->resource, $background));
- imagecopyresampled($n, $this->resource, 0, 0, 0, 0, $w, $h, $w, $h);
- imagedestroy($this->resource);
- $this->resource = $n;
- return $this;
- }
- /**
- * Do the image resize.
- *
- * @return $this
- */
- protected function doResize($bg, $target_width, $target_height, $new_width, $new_height)
- {
- $width = $this->width();
- $height = $this->height();
- $n = imagecreatetruecolor($target_width, $target_height);
- if ($bg != 'transparent') {
- imagefill($n, 0, 0, ImageColor::gdAllocate($this->resource, $bg));
- } else {
- imagealphablending($n, false);
- $color = ImageColor::gdAllocate($this->resource, 'transparent');
- imagefill($n, 0, 0, $color);
- imagesavealpha($n, true);
- }
- imagecopyresampled($n, $this->resource, ($target_width - $new_width) / 2, ($target_height - $new_height) / 2, 0, 0, $new_width, $new_height, $width, $height);
- imagedestroy($this->resource);
- $this->resource = $n;
- return $this;
- }
- /**
- * {@inheritdoc}
- */
- public function crop($x, $y, $width, $height)
- {
- $destination = imagecreatetruecolor($width, $height);
- imagealphablending($destination, false);
- imagesavealpha($destination, true);
- imagecopy($destination, $this->resource, 0, 0, $x, $y, $this->width(), $this->height());
- imagedestroy($this->resource);
- $this->resource = $destination;
- return $this;
- }
- /**
- * {@inheritdoc}
- */
- public function negate()
- {
- imagefilter($this->resource, IMG_FILTER_NEGATE);
- return $this;
- }
- /**
- * {@inheritdoc}
- */
- public function brightness($brightness)
- {
- imagefilter($this->resource, IMG_FILTER_BRIGHTNESS, $brightness);
- return $this;
- }
- /**
- * {@inheritdoc}
- */
- public function contrast($contrast)
- {
- imagefilter($this->resource, IMG_FILTER_CONTRAST, $contrast);
- return $this;
- }
- /**
- * {@inheritdoc}
- */
- public function grayscale()
- {
- imagefilter($this->resource, IMG_FILTER_GRAYSCALE);
- return $this;
- }
- /**
- * {@inheritdoc}
- */
- public function emboss()
- {
- imagefilter($this->resource, IMG_FILTER_EMBOSS);
- return $this;
- }
- /**
- * {@inheritdoc}
- */
- public function smooth($p)
- {
- imagefilter($this->resource, IMG_FILTER_SMOOTH, $p);
- return $this;
- }
- /**
- * {@inheritdoc}
- */
- public function sharp()
- {
- imagefilter($this->resource, IMG_FILTER_MEAN_REMOVAL);
- return $this;
- }
- /**
- * {@inheritdoc}
- */
- public function edge()
- {
- imagefilter($this->resource, IMG_FILTER_EDGEDETECT);
- return $this;
- }
- /**
- * {@inheritdoc}
- */
- public function colorize($red, $green, $blue)
- {
- imagefilter($this->resource, IMG_FILTER_COLORIZE, $red, $green, $blue);
- return $this;
- }
- /**
- * {@inheritdoc}
- */
- public function sepia()
- {
- imagefilter($this->resource, IMG_FILTER_GRAYSCALE);
- imagefilter($this->resource, IMG_FILTER_COLORIZE, 100, 50, 0);
- return $this;
- }
- /**
- * {@inheritdoc}
- */
- public function gaussianBlur($blurFactor = 1)
- {
- $blurFactor = round($blurFactor); // blurFactor has to be an integer
- $originalWidth = $this->width();
- $originalHeight = $this->height();
- $smallestWidth = ceil($originalWidth * pow(0.5, $blurFactor));
- $smallestHeight = ceil($originalHeight * pow(0.5, $blurFactor));
- // for the first run, the previous image is the original input
- $prevImage = $this->resource;
- $prevWidth = $originalWidth;
- $prevHeight = $originalHeight;
- // scale way down and gradually scale back up, blurring all the way
- for ($i = 0; $i < $blurFactor; ++$i) {
- // determine dimensions of next image
- $nextWidth = $smallestWidth * pow(2, $i);
- $nextHeight = $smallestHeight * pow(2, $i);
- // resize previous image to next size
- $nextImage = imagecreatetruecolor($nextWidth, $nextHeight);
- imagecopyresized($nextImage, $prevImage, 0, 0, 0, 0,
- $nextWidth, $nextHeight, $prevWidth, $prevHeight);
- // apply blur filter
- imagefilter($nextImage, IMG_FILTER_GAUSSIAN_BLUR);
- // now the new image becomes the previous image for the next step
- $prevImage = $nextImage;
- $prevWidth = $nextWidth;
- $prevHeight = $nextHeight;
- }
- // scale back to original size and blur one more time
- imagecopyresized($this->resource, $nextImage,
- 0, 0, 0, 0, $originalWidth, $originalHeight, $nextWidth, $nextHeight);
- imagefilter($this->resource, IMG_FILTER_GAUSSIAN_BLUR);
- // clean up
- imagedestroy($prevImage);
- return $this;
- }
- /**
- * {@inheritdoc}
- */
- public function merge(Image $other, $x = 0, $y = 0, $width = null, $height = null)
- {
- $other = clone $other;
- $other->init();
- $other->applyOperations();
- imagealphablending($this->resource, true);
- if (null == $width) {
- $width = $other->width();
- }
- if (null == $height) {
- $height = $other->height();
- }
- imagecopyresampled($this->resource, $other->getAdapter()->getResource(), $x, $y, 0, 0, $width, $height, $width, $height);
- return $this;
- }
- /**
- * {@inheritdoc}
- */
- public function rotate($angle, $background = 0xffffff)
- {
- $this->resource = imagerotate($this->resource, $angle, ImageColor::gdAllocate($this->resource, $background));
- imagealphablending($this->resource, true);
- imagesavealpha($this->resource, true);
- return $this;
- }
- /**
- * {@inheritdoc}
- */
- public function fill($color = 0xffffff, $x = 0, $y = 0)
- {
- imagealphablending($this->resource, false);
- imagefill($this->resource, $x, $y, ImageColor::gdAllocate($this->resource, $color));
- return $this;
- }
- /**
- * {@inheritdoc}
- */
- public function write($font, $text, $x = 0, $y = 0, $size = 12, $angle = 0, $color = 0x000000, $align = 'left')
- {
- imagealphablending($this->resource, true);
- if ($align != 'left') {
- $sim_size = self::TTFBox($font, $text, $size, $angle);
- if ($align == 'center') {
- $x -= $sim_size['width'] / 2;
- }
- if ($align == 'right') {
- $x -= $sim_size['width'];
- }
- }
- imagettftext($this->resource, $size, $angle, $x, $y, ImageColor::gdAllocate($this->resource, $color), $font, $text);
- return $this;
- }
- /**
- * {@inheritdoc}
- */
- public function rectangle($x1, $y1, $x2, $y2, $color, $filled = false)
- {
- if ($filled) {
- imagefilledrectangle($this->resource, $x1, $y1, $x2, $y2, ImageColor::gdAllocate($this->resource, $color));
- } else {
- imagerectangle($this->resource, $x1, $y1, $x2, $y2, ImageColor::gdAllocate($this->resource, $color));
- }
- return $this;
- }
- /**
- * {@inheritdoc}
- */
- public function roundedRectangle($x1, $y1, $x2, $y2, $radius, $color, $filled = false)
- {
- if ($color) {
- $color = ImageColor::gdAllocate($this->resource, $color);
- }
- if ($filled == true) {
- imagefilledrectangle($this->resource, $x1 + $radius, $y1, $x2 - $radius, $y2, $color);
- imagefilledrectangle($this->resource, $x1, $y1 + $radius, $x1 + $radius - 1, $y2 - $radius, $color);
- imagefilledrectangle($this->resource, $x2 - $radius + 1, $y1 + $radius, $x2, $y2 - $radius, $color);
- imagefilledarc($this->resource, $x1 + $radius, $y1 + $radius, $radius * 2, $radius * 2, 180, 270, $color, IMG_ARC_PIE);
- imagefilledarc($this->resource, $x2 - $radius, $y1 + $radius, $radius * 2, $radius * 2, 270, 360, $color, IMG_ARC_PIE);
- imagefilledarc($this->resource, $x1 + $radius, $y2 - $radius, $radius * 2, $radius * 2, 90, 180, $color, IMG_ARC_PIE);
- imagefilledarc($this->resource, $x2 - $radius, $y2 - $radius, $radius * 2, $radius * 2, 360, 90, $color, IMG_ARC_PIE);
- } else {
- imageline($this->resource, $x1 + $radius, $y1, $x2 - $radius, $y1, $color);
- imageline($this->resource, $x1 + $radius, $y2, $x2 - $radius, $y2, $color);
- imageline($this->resource, $x1, $y1 + $radius, $x1, $y2 - $radius, $color);
- imageline($this->resource, $x2, $y1 + $radius, $x2, $y2 - $radius, $color);
- imagearc($this->resource, $x1 + $radius, $y1 + $radius, $radius * 2, $radius * 2, 180, 270, $color);
- imagearc($this->resource, $x2 - $radius, $y1 + $radius, $radius * 2, $radius * 2, 270, 360, $color);
- imagearc($this->resource, $x1 + $radius, $y2 - $radius, $radius * 2, $radius * 2, 90, 180, $color);
- imagearc($this->resource, $x2 - $radius, $y2 - $radius, $radius * 2, $radius * 2, 360, 90, $color);
- }
- return $this;
- }
- /**
- * {@inheritdoc}
- */
- public function line($x1, $y1, $x2, $y2, $color = 0x000000)
- {
- imageline($this->resource, $x1, $y1, $x2, $y2, ImageColor::gdAllocate($this->resource, $color));
- return $this;
- }
- /**
- * {@inheritdoc}
- */
- public function ellipse($cx, $cy, $width, $height, $color = 0x000000, $filled = false)
- {
- if ($filled) {
- imagefilledellipse($this->resource, $cx, $cy, $width, $height, ImageColor::gdAllocate($this->resource, $color));
- } else {
- imageellipse($this->resource, $cx, $cy, $width, $height, ImageColor::gdAllocate($this->resource, $color));
- }
- return $this;
- }
- /**
- * {@inheritdoc}
- */
- public function circle($cx, $cy, $r, $color = 0x000000, $filled = false)
- {
- return $this->ellipse($cx, $cy, $r, $r, ImageColor::gdAllocate($this->resource, $color), $filled);
- }
- /**
- * {@inheritdoc}
- */
- public function polygon(array $points, $color, $filled = false)
- {
- if ($filled) {
- imagefilledpolygon($this->resource, $points, count($points) / 2, ImageColor::gdAllocate($this->resource, $color));
- } else {
- imagepolygon($this->resource, $points, count($points) / 2, ImageColor::gdAllocate($this->resource, $color));
- }
- return $this;
- }
- /**
- * {@inheritdoc}
- */
- public function flip($flipVertical, $flipHorizontal)
- {
- if (!$flipVertical && !$flipHorizontal) {
- return $this;
- }
- if (function_exists('imageflip')) {
- if ($flipVertical && $flipHorizontal) {
- $flipMode = \IMG_FLIP_BOTH;
- } elseif ($flipVertical && !$flipHorizontal) {
- $flipMode = \IMG_FLIP_VERTICAL;
- } elseif (!$flipVertical && $flipHorizontal) {
- $flipMode = \IMG_FLIP_HORIZONTAL;
- }
- imageflip($this->resource, $flipMode);
- } else {
- $width = $this->width();
- $height = $this->height();
- $src_x = 0;
- $src_y = 0;
- $src_width = $width;
- $src_height = $height;
- if ($flipVertical) {
- $src_y = $height - 1;
- $src_height = -$height;
- }
- if ($flipHorizontal) {
- $src_x = $width - 1;
- $src_width = -$width;
- }
- $imgdest = imagecreatetruecolor($width, $height);
- imagealphablending($imgdest, false);
- imagesavealpha($imgdest, true);
- if (imagecopyresampled($imgdest, $this->resource, 0, 0, $src_x, $src_y, $width, $height, $src_width, $src_height)) {
- imagedestroy($this->resource);
- $this->resource = $imgdest;
- }
- }
- return $this;
- }
- /**
- * {@inheritdoc}
- */
- public function width()
- {
- if (null === $this->resource) {
- $this->init();
- }
- return imagesx($this->resource);
- }
- /**
- * {@inheritdoc}
- */
- public function height()
- {
- if (null === $this->resource) {
- $this->init();
- }
- return imagesy($this->resource);
- }
- protected function createImage($width, $height)
- {
- $this->resource = imagecreatetruecolor($width, $height);
- }
- protected function createImageFromData($data)
- {
- $this->resource = @imagecreatefromstring($data);
- }
- /**
- * Converts the image to true color.
- */
- protected function convertToTrueColor()
- {
- if (!imageistruecolor($this->resource)) {
- if (function_exists('imagepalettetotruecolor')) {
- // Available in PHP 5.5
- imagepalettetotruecolor($this->resource);
- } else {
- $transparentIndex = imagecolortransparent($this->resource);
- $w = $this->width();
- $h = $this->height();
- $img = imagecreatetruecolor($w, $h);
- imagecopy($img, $this->resource, 0, 0, 0, 0, $w, $h);
- if ($transparentIndex != -1) {
- $width = $this->width();
- $height = $this->height();
- imagealphablending($img, false);
- imagesavealpha($img, true);
- for ($x = 0; $x < $width; ++$x) {
- for ($y = 0; $y < $height; ++$y) {
- if (imagecolorat($this->resource, $x, $y) == $transparentIndex) {
- imagesetpixel($img, $x, $y, 127 << 24);
- }
- }
- }
- }
- $this->resource = $img;
- }
- }
- imagesavealpha($this->resource, true);
- }
- /**
- * {@inheritdoc}
- */
- public function saveGif($file)
- {
- $transColor = imagecolorallocatealpha($this->resource, 255, 255, 255, 127);
- imagecolortransparent($this->resource, $transColor);
- imagegif($this->resource, $file);
- return $this;
- }
- /**
- * {@inheritdoc}
- */
- public function savePng($file)
- {
- imagepng($this->resource, $file);
- return $this;
- }
- /**
- * {@inheritdoc}
- */
- public function saveJpeg($file, $quality)
- {
- imagejpeg($this->resource, $file, $quality);
- return $this;
- }
- /**
- * Try to open the file using jpeg.
- */
- protected function openJpeg($file)
- {
- $this->resource = @imagecreatefromjpeg($file);
- }
- /**
- * Try to open the file using gif.
- */
- protected function openGif($file)
- {
- $this->resource = @imagecreatefromgif($file);
- }
- /**
- * Try to open the file using PNG.
- */
- protected function openPng($file)
- {
- $this->resource = @imagecreatefrompng($file);
- }
- /**
- * Does this adapter supports type ?
- */
- protected function supports($type)
- {
- return imagetypes() & self::$gdTypes[$type];
- }
- protected function getColor($x, $y)
- {
- return imagecolorat($this->resource, $x, $y);
- }
- /**
- * {@inheritdoc}
- */
- public function enableProgressive()
- {
- imageinterlace($this->resource, 1);
- return $this;
- }
- }
|