| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323 |
- <?php
- /**
- * Created by PhpStorm.
- * User: AlexLcDee
- * Date: 15.02.2017
- * Time: 17:34
- */
- namespace yiins\components;
- class ImageGD
- {
- const WM_POS_LEFT_TOP = 'leftTop';
- const WM_POS_CENTER_TOP = 'top';
- const WM_POS_RIGHT_TOP = 'rightTop';
- const WM_POS_LEFT_CENTER = 'leftCenter';
- const WM_POS_CENTER_CENTER = 'center';
- const WM_POS_RIGHT_CENTER = 'rightCenter';
- const WM_POS_LEFT_BOTTOM = 'leftBottom';
- const WM_POS_CENTER_BOTTOM = 'bottom';
- const WM_POS_RIGHT_BOTTOM = 'rightBottom';
- protected $sourceResource;
- protected $destinationResource;
- protected $watermarkSource;
- protected $imageSize;
- protected $qualityMultiplier = 1;
- protected $mustCopy = false;
- protected $outputWidth;
- protected $outputHeight;
- protected $quality = 100;
- protected $offsetX = 0;
- protected $offsetY = 0;
- protected $cropWidth = 0;
- protected $cropHeight = 0;
- private function __construct($sourcePath)
- {
- $this->imageSize = getimagesize($sourcePath);
- $this->outputWidth = $this->cropWidth = $this->imageSize[0];
- $this->outputHeight = $this->cropHeight = $this->imageSize[1];
- $this->destinationResource = imagecreatetruecolor($this->outputWidth, $this->outputHeight);
- list($creationFunction, $outputFunction) = $this->functionNames();
- $this->sourceResource = $creationFunction($sourcePath);
- $this->outputFunction = $outputFunction;
- }
- /**
- * Set up the appropriate image handling functions based on the original image's mime type
- * @return array
- */
- protected function functionNames()
- {
- $size = $this->imageSize;
- switch ($size['mime']) {
- case 'image/gif':
- // We will be converting GIFs to PNGs to avoid transparency issues when resizing GIFs
- // This is maybe not the ideal solution, but IE6 can suck it
- $creationFunction = 'ImageCreateFromGif';
- $outputFunction = 'ImagePng';
- break;
- case 'image/x-png':
- case 'image/png':
- $creationFunction = 'ImageCreateFromPng';
- $outputFunction = 'ImagePng';
- $this->qualityMultiplier = 0.01;
- break;
- default:
- $creationFunction = 'ImageCreateFromJpeg';
- $outputFunction = 'ImageJpeg';
- break;
- }
- return [
- $creationFunction,
- $outputFunction,
- ];
- }
- public static function resize($sourcePath, $width, $height, $offsetX, $offsetY, $cropWidth, $cropHeight)
- {
- $instance = new static($sourcePath);
- $instance->outputWidth($width);
- $instance->outputHeight($height);
- $instance->offsetX($offsetX);
- $instance->offsetY($offsetY);
- $instance->cropWidth($cropWidth);
- $instance->cropHeight($cropHeight);
- $instance->copyResampled($instance->sourceResource, $instance->destinationResource);
- return $instance;
- }
- public function outputWidth($width, $reset = true)
- {
- $this->outputWidth = $width;
- if ($reset) {
- $this->setDestination();
- }
- return $this;
- }
- protected function setDestination()
- {
- $this->destinationResource = imageCreateTruecolor($this->outputWidth, $this->outputHeight);
- $this->preserveAlfa();
- if ($this->mustCopy) {
- call_user_func_array([$this, $this->mustCopy], [$this->sourceResource, $this->destinationResource]);
- }
- }
- private function preserveAlfa()
- {
- if (in_array($this->imageSize['mime'], array('image/gif', 'image/png'))) {
- // If this is a GIF or a PNG, we need to set up transparency
- imageAlphaBlending($this->destinationResource, false);
- imageSaveAlpha($this->destinationResource, true);
- }
- }
- public function outputHeight($height, $reset = true)
- {
- $this->outputHeight = $height;
- if ($reset) {
- $this->setDestination();
- }
- return $this;
- }
- public function offsetX($value)
- {
- $this->offsetX = $value;
- if ($this->mustCopy) {
- call_user_func_array([$this, $this->mustCopy], [$this->sourceResource, $this->destinationResource]);
- }
- return $this;
- }
- public function offsetY($value)
- {
- $this->offsetY = $value;
- if ($this->mustCopy) {
- call_user_func_array([$this, $this->mustCopy], [$this->sourceResource, $this->destinationResource]);
- }
- return $this;
- }
- public function cropWidth($width)
- {
- $this->cropWidth = $width;
- if ($this->mustCopy) {
- call_user_func_array([$this, $this->mustCopy], [$this->sourceResource, $this->destinationResource]);
- }
- return $this;
- }
- public function cropHeight($height)
- {
- $this->cropHeight = $height;
- if ($this->mustCopy) {
- call_user_func_array([$this, $this->mustCopy], [$this->sourceResource, $this->destinationResource]);
- }
- return $this;
- }
- public function copyResampled($source, $destination)
- {
- $this->mustCopy = 'copyResampled';
- imageCopyResampled(
- $destination,
- $source,
- 0, 0,
- $this->offsetX,
- $this->offsetY,
- $this->outputWidth,
- $this->outputHeight,
- $this->cropWidth,
- $this->cropHeight);
- return $this;
- }
- public static function watermark($sourcePath, $watermarkPath, $position = false)
- {
- if (!$position) {
- $position = static::WM_POS_CENTER_CENTER;
- }
- $instance = new static($sourcePath);
- $instance->setWatermark($watermarkPath);
- $watermarkSizes = getimagesize($watermarkPath);
- $instance->copy($instance->sourceResource, $instance->destinationResource);
- $offsets = $instance->calculatePosition($position,
- ['width' => $watermarkSizes[0], 'height' => $watermarkSizes[1]]);
- $instance->mustCopy = false;
- $instance->offsetX($offsets['x']);
- $instance->offsetY($offsets['y']);
- $instance->outputWidth($watermarkSizes[0], false);
- $instance->outputHeight($watermarkSizes[1], false);
- $instance->copy($instance->watermarkSource, $instance->destinationResource);
- return $instance;
- }
- protected function setWatermark($watermarkPath)
- {
- $this->watermarkSource = imagecreatefrompng($watermarkPath);
- return $this;
- }
- public function copy($source, $destination)
- {
- $this->mustCopy = 'copy';
- imagecopy(
- $destination,
- $source,
- $this->offsetX, $this->offsetY,
- 0,
- 0,
- $this->outputWidth,
- $this->outputHeight
- );
- return $this;
- }
- protected function calculatePosition($position, $wmSizes = ['width' => 0, 'height' => 0])
- {
- return call_user_func_array([$this, 'pos' . ucfirst($position)], $wmSizes);
- }
- public function quality($quality)
- {
- $this->quality = $quality;
- return $this;
- }
- public function output($destination = null)
- {
- $outputFunction = $this->outputFunction;
- $path = dirname($destination);
- if (!file_exists($path)) {
- mkdir($path, 0777, true);
- }
- $outputFunction($this->destinationResource, $destination, $this->quality * $this->qualityMultiplier);
- }
- protected function posLeftTop($width, $height)
- {
- return [
- 'x' => 10,
- 'y' => 10,
- ];
- }
- protected function posTop($width, $height)
- {
- return [
- 'x' => $this->outputWidth / 2 - $width / 2,
- 'y' => 10,
- ];
- }
- protected function posRightTop($width, $height)
- {
- return [
- 'x' => $this->outputWidth - $width - 10,
- 'y' => 10,
- ];
- }
- protected function posLeftCenter($width, $height)
- {
- return [
- 'x' => 10,
- 'y' => $this->outputHeight / 2 - $height / 2,
- ];
- }
- protected function posCenter($width, $height)
- {
- return [
- 'x' => $this->outputWidth / 2 - $width / 2,
- 'y' => $this->outputHeight / 2 - $height / 2,
- ];
- }
- protected function posRightCenter($width, $height)
- {
- return [
- 'x' => $this->outputWidth - $width - 10,
- 'y' => $this->outputHeight / 2 - $height / 2,
- ];
- }
- protected function posLeftBottom($width, $height)
- {
- return [
- 'x' => 10,
- 'y' => $this->outputHeight - $height - 10,
- ];
- }
- protected function posBottom($width, $height)
- {
- return [
- 'x' => $this->outputWidth / 2 - $width / 2,
- 'y' => $this->outputHeight - $height - 10,
- ];
- }
- protected function posRightBottom($width, $height)
- {
- return [
- 'x' => $this->outputWidth - $width - 10,
- 'y' => $this->outputHeight - $height - 10,
- ];
- }
- }
|