1048 lines
26 KiB
PHP
1048 lines
26 KiB
PHP
<?php namespace ZN\Image;
|
|
/**
|
|
* ZN PHP Web Framework
|
|
*
|
|
* "Simplicity is the ultimate sophistication." ~ Da Vinci
|
|
*
|
|
* @package ZN
|
|
* @license MIT [http://opensource.org/licenses/MIT]
|
|
* @author Ozan UYKUN [ozan@znframework.com]
|
|
*/
|
|
|
|
use stdClass;
|
|
use ZN\Base;
|
|
use ZN\Helper;
|
|
use ZN\Singleton;
|
|
use ZN\Ability\Revolving;
|
|
use ZN\Image\Exception\FontNotFoundException;
|
|
use ZN\Image\Exception\InvalidArgumentException;
|
|
use ZN\Image\Exception\InvalidImageFileException;
|
|
|
|
#[\AllowDynamicProperties]
|
|
|
|
class GD implements GDInterface
|
|
{
|
|
use Revolving, CallableFilterMethod;
|
|
|
|
/**
|
|
* Call callable method
|
|
*
|
|
* @const string
|
|
*/
|
|
const call = 'callable';
|
|
|
|
/**
|
|
* Keeps canvas settings
|
|
*
|
|
* @var resource
|
|
*/
|
|
protected $canvas;
|
|
|
|
/**
|
|
* Output status
|
|
*
|
|
* @var bool
|
|
*/
|
|
protected $output = true;
|
|
|
|
/**
|
|
* Keeps mime class
|
|
*/
|
|
protected $mime;
|
|
|
|
/**
|
|
* Keeps mime class
|
|
*/
|
|
protected $imageSize;
|
|
|
|
/**
|
|
* Keeps mime type
|
|
*/
|
|
protected $mimeType;
|
|
|
|
/**
|
|
* Keeps ttf font path
|
|
*/
|
|
protected $load;
|
|
|
|
/**
|
|
* Magic Constructor
|
|
*/
|
|
public function __construct()
|
|
{
|
|
$this->mime = Singleton::class('ZN\Helpers\Mime');
|
|
}
|
|
|
|
/**
|
|
* Get info
|
|
*
|
|
* @return array
|
|
*/
|
|
public function info() : array
|
|
{
|
|
return gd_info();
|
|
}
|
|
|
|
/**
|
|
* Load ttf font
|
|
*
|
|
* @return GD
|
|
*/
|
|
public function load($ttfpath) : GD
|
|
{
|
|
$this->load = $ttfpath;
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Sets canvas
|
|
*
|
|
* @param mixed $width
|
|
* @param mixed $height = NULL
|
|
* @param mixed $rgb = 'transparent'
|
|
* @param mixed $real = false
|
|
*
|
|
* @return GD
|
|
*/
|
|
public function canvas($width, $height = NULL, $rgb = 'transparent', $real = false) : GD
|
|
{
|
|
if( ! is_numeric($width) )
|
|
{
|
|
# width -> image
|
|
if( $this->mime->type($width, 0) === 'image' )
|
|
{
|
|
# width -> image
|
|
# height -> width
|
|
# rgb -> height
|
|
$this->createImageCanvas($width, $height, $rgb);
|
|
}
|
|
else
|
|
{
|
|
throw new InvalidImageFileException(NULL, $width);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
$this->createEmptyCanvas($width, $height, $rgb, $real);
|
|
}
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Creates form
|
|
*
|
|
* @param string $source
|
|
*
|
|
* @return resource
|
|
*/
|
|
public function createFrom(string $source)
|
|
{
|
|
$type = $this->mime->type($source, 1);
|
|
$function = 'imagecreatefrom' . ($type ?? 'jpeg');
|
|
|
|
if( ! function_exists($function) )
|
|
{
|
|
throw new InvalidImageFileException(NULL, $source); // @codeCoverageIgnore
|
|
}
|
|
|
|
return $function($source);
|
|
}
|
|
|
|
/**
|
|
* Set size
|
|
*
|
|
* @param string $fileName
|
|
*
|
|
* @return object
|
|
*/
|
|
public function size(string $fileName) : stdClass
|
|
{
|
|
$data = [];
|
|
|
|
if( in_array(strlen(pathinfo($fileName, PATHINFO_EXTENSION)), [3, 4]) && $this->mime->type($fileName, 0) === 'image' )
|
|
{
|
|
$data = getimagesize($fileName);
|
|
}
|
|
else if( is_string($fileName) )
|
|
{
|
|
$data = getimagesizefromstring($fileName);
|
|
}
|
|
|
|
if( empty($data) )
|
|
{
|
|
throw new InvalidArgumentException(NULL, '[file]');
|
|
}
|
|
|
|
return (object)
|
|
[
|
|
'width' => $data[0],
|
|
'height' => $data[1],
|
|
'extension' => $this->extension($data[2]),
|
|
'img' => $data[3],
|
|
'bits' => $data['bits'],
|
|
'mime' => $data['mime']
|
|
];
|
|
}
|
|
|
|
/**
|
|
* Get file extension
|
|
*
|
|
* @param string $type = 'jpeg'
|
|
* @param bool $dot = true
|
|
*
|
|
* @return string
|
|
*/
|
|
public function extension(string $type = 'jpeg', bool $dot = true) : string
|
|
{
|
|
return image_type_to_extension(Helper::toConstant($type, 'IMAGETYPE_'), $dot);
|
|
}
|
|
|
|
/**
|
|
* Get mime type
|
|
*
|
|
* @param string $type = 'jpeg'
|
|
*
|
|
* @return string
|
|
*/
|
|
public function mime(string $type = 'jpeg') : string
|
|
{
|
|
return image_type_to_mime_type(Helper::toConstant($type, 'IMAGETYPE_'));
|
|
}
|
|
|
|
/**
|
|
* Sets alpha blending
|
|
*
|
|
* @param bool $blendMode = NULL
|
|
*
|
|
* @return GD
|
|
*/
|
|
public function alphaBlending(?bool $blendMode = NULL) : GD
|
|
{
|
|
imagealphablending($this->canvas, (bool) $blendMode);
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Sets save alpha
|
|
*
|
|
* @param bool $save = true
|
|
*
|
|
* @return GD
|
|
*/
|
|
public function saveAlpha(bool $save = true) : GD
|
|
{
|
|
imagesavealpha($this->canvas, $save);
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Sets smooth
|
|
*
|
|
* @param bool $mode = true
|
|
*
|
|
* @return GD
|
|
*/
|
|
public function smooth(bool $mode = true) : GD
|
|
{
|
|
imageantialias($this->canvas, $mode);
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Creates Arc
|
|
*
|
|
* @param array $settings []
|
|
*
|
|
* @return GD
|
|
*/
|
|
public function arc(array $settings = []) : GD
|
|
{
|
|
$x = $settings['x'] ?? $this->x ?? 0;
|
|
$y = $settings['y'] ?? $this->y ?? 0;
|
|
$width = $settings['width'] ?? $this->width ?? 100;
|
|
$height = $settings['height'] ?? $this->height ?? 100;
|
|
$start = $settings['start'] ?? $this->start ?? 0;
|
|
$end = $settings['end'] ?? $this->end ?? 360;
|
|
$color = $settings['color'] ?? $this->color ?? '0|0|0';
|
|
$style = $settings['type'] ?? $this->type ?? NULL;
|
|
|
|
if( $style === NULL )
|
|
{
|
|
imagearc($this->canvas, $x, $y, $width, $height, $start, $end, $this->allocate($color));
|
|
}
|
|
else
|
|
{
|
|
imagefilledarc
|
|
(
|
|
$this->canvas, $x, $y, $width, $height, $start, $end,
|
|
$this->allocate($color),
|
|
Helper::toConstant($style, 'IMG_ARC_')
|
|
);
|
|
}
|
|
|
|
$this->defaultRevolvingVariables(['x', 'y', 'width', 'height', 'start', 'end', 'color', 'type']);
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Creates Ellipse
|
|
*
|
|
* @param array $settings []
|
|
*
|
|
* @return GD
|
|
*/
|
|
public function ellipse(array $settings = []) : GD
|
|
{
|
|
$x = $settings['x'] ?? $this->x ?? 0;
|
|
$y = $settings['y'] ?? $this->y ?? 0;
|
|
$width = $settings['width'] ?? $this->width ?? 100;
|
|
$height = $settings['height'] ?? $this->height ?? 100;
|
|
$color = $settings['color'] ?? $this->color ?? '0|0|0';
|
|
$style = $settings['type'] ?? $this->type ?? NULL;
|
|
|
|
if( $style === NULL )
|
|
{
|
|
imageellipse($this->canvas, $x, $y, $width, $height, $this->allocate($color));
|
|
}
|
|
else
|
|
{
|
|
imagefilledellipse($this->canvas, $x, $y, $width, $height, $this->allocate($color));
|
|
}
|
|
|
|
$this->defaultRevolvingVariables(['x', 'y' ,'width', 'height', 'color', 'type']);
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Creates Polygon
|
|
*
|
|
* @param array $settings []
|
|
*
|
|
* @return GD
|
|
*/
|
|
public function polygon(array $settings = []) : GD
|
|
{
|
|
$points = $settings['points'] ?? $this->points ?? 0;
|
|
$color = $settings['color'] ?? $this->color ?? '0|0|0';
|
|
$style = $settings['type'] ?? $this->type ?? NULL;
|
|
|
|
if( $style === NULL )
|
|
{
|
|
imagepolygon($this->canvas, $points, $this->allocate($color));
|
|
}
|
|
else
|
|
{
|
|
imagefilledpolygon($this->canvas, $points, $this->allocate($color));
|
|
}
|
|
|
|
$this->defaultRevolvingVariables(['points', 'color', 'type']);
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Creates Rectangle
|
|
*
|
|
* @param array $settings []
|
|
*
|
|
* @return GD
|
|
*/
|
|
public function rectangle(array $settings = []) : GD
|
|
{
|
|
$x = $settings['x'] ?? $this->x ?? 0;
|
|
$y = $settings['y'] ?? $this->y ?? 0;
|
|
$width = $settings['width'] ?? $this->width ?? 100;
|
|
$height = $settings['height'] ?? $this->height ?? 100;
|
|
$color = $settings['color'] ?? $this->color ?? '0|0|0';
|
|
$style = $settings['type'] ?? $this->type ?? NULL;
|
|
|
|
$width += $x;
|
|
$height += $y;
|
|
|
|
if( $style === NULL )
|
|
{
|
|
imagerectangle($this->canvas, $x, $y, $width, $height, $this->allocate($color));
|
|
}
|
|
else
|
|
{
|
|
imagefilledrectangle($this->canvas, $x, $y, $width, $height, $this->allocate($color));
|
|
}
|
|
|
|
$this->defaultRevolvingVariables(['x', 'y' ,'width', 'height', 'color', 'type']);
|
|
|
|
return $this;
|
|
}
|
|
|
|
|
|
/**
|
|
* Fill
|
|
*
|
|
* @param array $settings []
|
|
*
|
|
* @return GD
|
|
*/
|
|
public function fill(array $settings = []) : GD
|
|
{
|
|
$x = $settings['x'] ?? $this->x ?? 0;
|
|
$y = $settings['y'] ?? $this->y ?? 0;
|
|
$color = $settings['color'] ?? $this->color ?? '0|0|0';
|
|
$borderColor = $settings['borderColor'] ?? $this->borderColor ?? NULL;
|
|
|
|
if( $borderColor === NULL )
|
|
{
|
|
imagefill($this->canvas, $x, $y, $this->allocate($color));
|
|
}
|
|
else
|
|
{
|
|
imagefilltoborder($this->canvas, $x, $y, $this->allocate($borderColor), $this->allocate($color));
|
|
}
|
|
|
|
$this->defaultRevolvingVariables(['x', 'y', 'color', 'borderColor']);
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Filter
|
|
*
|
|
* @param string $filter
|
|
* @param int $arg1 = NULL
|
|
* @param int $arg2 = NULL
|
|
* @param int $arg3 = NULL
|
|
* @param int $arg4 = NULL
|
|
*
|
|
* @return GD
|
|
*/
|
|
public function filter(string $filter, ?int $arg1 = NULL, ?int $arg2 = NULL, ?int $arg3 = NULL, ?int $arg4 = NULL) : GD
|
|
{
|
|
$filters = Singleton::class('ZN\DataTypes\Collection')->data(func_get_args())
|
|
->removeFirst()
|
|
->deleteElement(NULL)
|
|
->get();
|
|
|
|
imagefilter($this->canvas, Helper::toConstant($filter, 'IMG_FILTER_'), ...$filters);
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Flip
|
|
*
|
|
* @param string $type = 'both'
|
|
*
|
|
* @return GD
|
|
*/
|
|
public function flip(string $type = 'both') : GD
|
|
{
|
|
imageflip($this->canvas, Helper::toConstant($type, 'IMG_FLIP_'));
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Creates char
|
|
*
|
|
* @param string $text
|
|
* @param array $settings = []
|
|
*
|
|
* @return GD
|
|
*/
|
|
public function char(string $char, array $settings = [], $function = 'char') : GD
|
|
{
|
|
$x = $settings['x'] ?? $this->x ?? 0;
|
|
$y = $settings['y'] ?? $this->y ?? 0;
|
|
$font = $settings['font'] ?? $this->font ?? 1;
|
|
$color = $settings['color'] ?? $this->color ?? '0|0|0';
|
|
$type = $settings['type'] ?? $this->type ?? NULL;
|
|
$method = 'image' . $function;
|
|
|
|
if( $type === 'vertical')
|
|
{
|
|
$method .= 'up';
|
|
|
|
$method($this->canvas, $font, $x, $y, $char, $this->allocate($color));
|
|
}
|
|
else
|
|
{
|
|
$method($this->canvas, $font, $x, $y, $char, $this->allocate($color));
|
|
}
|
|
|
|
$this->defaultRevolvingVariables(['x', 'y' ,'font', 'color', 'type']);
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Creates ttftext
|
|
*
|
|
* @param string $text
|
|
* @param array $settings = []
|
|
*
|
|
* @return GD
|
|
*/
|
|
public function ttftext(string $text, array $settings = []) : GD
|
|
{
|
|
$fontSize = $settings['fontSize'] ?? $this->fontSize ?? 14;
|
|
$angle = $settings['angle'] ?? $this->angle ?? 0;
|
|
$x = $settings['x'] ?? $this->x ?? 0;
|
|
$y = $settings['y'] ?? $this->y ?? 0;
|
|
$color = $settings['color'] ?? $this->color ?? '0|0|0';
|
|
$load = $settings['load'] ?? $this->load ?? '';
|
|
|
|
$load = Base::suffix($load, '.ttf');
|
|
|
|
if( ! is_file($load) )
|
|
{
|
|
throw new FontNotFoundException(NULL, $load);
|
|
}
|
|
|
|
imagettftext($this->canvas, $fontSize, $angle, $x, $y, $this->allocate($color), $load, $text);
|
|
|
|
$this->defaultRevolvingVariables(['fontSize', 'angle', 'x', 'y', 'color']);
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Creates text
|
|
*
|
|
* @param string $text
|
|
* @param array $settings = []
|
|
*
|
|
* @return GD
|
|
*/
|
|
public function text(string $text, array $settings = []) : GD
|
|
{
|
|
if( $settings['load'] ?? $this->load )
|
|
{
|
|
return $this->ttftext($text, $settings);
|
|
}
|
|
|
|
return $this->char($text, $settings, 'string');
|
|
}
|
|
|
|
/**
|
|
* Set convolution
|
|
*
|
|
* @param array $matrix
|
|
* @param float $div = 0
|
|
* @param float $offset = 0
|
|
*
|
|
* @return GD
|
|
*/
|
|
public function convolution(array $matrix, Float $div = 0, Float $offset = 0) : GD
|
|
{
|
|
imageconvolution($this->canvas, $matrix, $div, $offset);
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Set interlace
|
|
*
|
|
* @param int $interlace = 0
|
|
*
|
|
* @return GD
|
|
*/
|
|
public function interlace(int $interlace = 0) : GD
|
|
{
|
|
imageinterlace($this->canvas, $interlace);
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Copy
|
|
*
|
|
* @param string|resource $source
|
|
* @param array $settings = []
|
|
*
|
|
* @return GD
|
|
*/
|
|
public function copy($source, array $settings = []) : GD
|
|
{
|
|
if( is_file($file = $source) )
|
|
{
|
|
$source = $this->createFrom($source);
|
|
}
|
|
|
|
if( ! Base::isResourceObject($source) )
|
|
{
|
|
throw new InvalidArgumentException(NULL, '[resource]'); // @codeCoverageIgnore
|
|
}
|
|
|
|
$this->alignImageWatermark($file);
|
|
|
|
$xt = $settings['xt'] ?? $this->target[0] ?? 0;
|
|
$yt = $settings['yt'] ?? $this->target[1] ?? 0;
|
|
$xs = $settings['xs'] ?? $this->source[0] ?? 0;
|
|
$ys = $settings['ys'] ?? $this->source[1] ?? 0;
|
|
$width = $settings['width'] ?? $this->width ?? 0;
|
|
$height = $settings['height'] ?? $this->height ?? 0;
|
|
|
|
imagecopy($this->canvas, $source, $xt, $yt, $xs, $ys, $width, $height);
|
|
|
|
$this->defaultRevolvingVariables(['target', 'source' ,'width', 'height']);
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Mix
|
|
*
|
|
* @param string|resource $source
|
|
* @param array $settings = []
|
|
*
|
|
* @return GD
|
|
*/
|
|
public function mix($source, array $settings = [], $function = 'imagecopymerge') : GD
|
|
{
|
|
if( is_file($file = $source) )
|
|
{
|
|
$source = $this->createFrom($source);
|
|
}
|
|
|
|
if( ! Base::isResourceObject($source) )
|
|
{
|
|
throw new InvalidArgumentException(NULL, '[resource]'); // @codeCoverageIgnore
|
|
}
|
|
|
|
$this->alignImageWatermark($file);
|
|
|
|
$xt = $settings['xt'] ?? $this->target[0] ?? 0;
|
|
$yt = $settings['yt'] ?? $this->target[1] ?? 0;
|
|
$xs = $settings['xs'] ?? $this->source[0] ?? 0;
|
|
$ys = $settings['ys'] ?? $this->source[1] ?? 0;
|
|
$width = $settings['width'] ?? $this->width ?? 0;
|
|
$height = $settings['height'] ?? $this->height ?? 0;
|
|
$percent = $settings['percent'] ?? $this->percent ?? 100;
|
|
|
|
$function($this->canvas, $source, $xt, $yt, $xs, $ys, $width, $height, $percent);
|
|
|
|
$this->defaultRevolvingVariables(['target', 'source' ,'width', 'height', 'percent']);
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Mixgray
|
|
*
|
|
* @param string|resource $source
|
|
* @param array $settings = []
|
|
*
|
|
* @return GD
|
|
*/
|
|
public function mixGray($source, array $settings = []) : GD
|
|
{
|
|
$this->mix($source, $settings, 'imagecopymergegray');
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Resize / Resample
|
|
*
|
|
* @param string|resource $source
|
|
* @param array $settings = []
|
|
*
|
|
* @return GD
|
|
*/
|
|
public function resample($source, array $settings = [], $function = 'imagecopyresampled') : GD
|
|
{
|
|
if( is_file($file = $source) )
|
|
{
|
|
$source = $this->createFrom($source);
|
|
}
|
|
|
|
if( ! Base::isResourceObject($source) )
|
|
{
|
|
throw new InvalidArgumentException(NULL, '[resource]'); // @codeCoverageIgnore
|
|
}
|
|
|
|
$this->alignImageWatermark($file);
|
|
|
|
$xt = $settings['xt'] ?? $this->target[0] ?? 0;
|
|
$yt = $settings['yt'] ?? $this->target[1] ?? 0;
|
|
$xs = $settings['xs'] ?? $this->source[0] ?? 0;
|
|
$ys = $settings['ys'] ?? $this->source[1] ?? 0;
|
|
$wt = $settings['wt'] ?? $this->width ?? $this->targetWidth ?? 0;
|
|
$ht = $settings['ht'] ?? $this->height ?? $this->targetHeight ?? 0;
|
|
$ws = $settings['ws'] ?? $this->sourceWidth ?? 0;
|
|
$hs = $settings['hs'] ?? $this->sourceHeight ?? 0;
|
|
|
|
$function($this->canvas, $source, $xt, $yt, $xs, $ys, $wt, $ht, $ws, $hs);
|
|
|
|
$this->defaultRevolvingVariables(['target', 'source' ,'width', 'height', 'sourceWidth', 'sourceHeight']);
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Resize
|
|
*
|
|
* @param string|resource $source
|
|
* @param array $settings = []
|
|
*
|
|
* @return GD
|
|
*/
|
|
public function resize($source, array $settings = []) : GD
|
|
{
|
|
$this->resample($source, $settings, 'imagecopyresized');
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Crop
|
|
*
|
|
* @param array $settings = []
|
|
*
|
|
* @return GD
|
|
*/
|
|
public function crop(array $settings = []) : GD
|
|
{
|
|
$sets =
|
|
[
|
|
'x' => $settings['x'] ?? $this->x ?? 0,
|
|
'y' => $settings['y'] ?? $this->y ?? 0,
|
|
'width' => $settings['width'] ?? $this->width ?? 100,
|
|
'height' => $settings['height'] ?? $this->height ?? 0,
|
|
|
|
];
|
|
|
|
$this->canvas = imagecrop($this->canvas, $sets);
|
|
|
|
$this->defaultRevolvingVariables(['x', 'y' ,'width', 'height']);
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Auto crop
|
|
*
|
|
* @param string $mode = 'default'
|
|
* @param int $threshold = .5
|
|
* @param int $color = -1
|
|
*
|
|
* @return GD
|
|
*/
|
|
public function autoCrop(string $mode = 'default', $threshold = .5, $color = -1) : GD
|
|
{
|
|
$this->canvas = imagecropauto
|
|
(
|
|
$this->canvas,
|
|
Helper::toConstant($mode, 'IMG_CROP_'),
|
|
$threshold,
|
|
$mode === 'threshold' ? $this->allocate($color) : $color
|
|
);
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Creates a line
|
|
*
|
|
* @param array $settings = []
|
|
*
|
|
* @return GD
|
|
*/
|
|
public function line(array $settings = []) : GD
|
|
{
|
|
$x1 = $settings['x1'] ?? $this->x1 ?? 0;
|
|
$y1 = $settings['y1'] ?? $this->y1 ?? 0;
|
|
$x2 = $settings['x2'] ?? $this->x2 ?? 0;
|
|
$y2 = $settings['y2'] ?? $this->y2 ?? 0;
|
|
$rgb = $settings['color'] ?? $this->color ?? '0|0|0';
|
|
$type = $settings['type'] ?? $this->type ?? 'solid';
|
|
|
|
if( $type === 'solid' )
|
|
{
|
|
imageline($this->canvas, $x1, $y1, $x2, $y2, $this->allocate($rgb));
|
|
}
|
|
elseif( $type === 'dashed' )
|
|
{
|
|
imagedashedline($this->canvas, $x1, $y1, $x2, $y2, $this->allocate($rgb));
|
|
}
|
|
|
|
$this->defaultRevolvingVariables(['x1', 'y1', 'x2', 'y2', 'color', 'type']);
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Get screenshot
|
|
*
|
|
* @return GD
|
|
*
|
|
* @codeCoverageIgnore
|
|
*/
|
|
public function screenshot() : GD
|
|
{
|
|
$this->canvas = imagegrabscreen();
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Set rotate
|
|
*
|
|
* @param float $angle
|
|
* @param string $spaceColor = '0|0|0'
|
|
*
|
|
* @return GD
|
|
*/
|
|
public function rotate(Float $angle, string $spaceColor = '0|0|0') : GD
|
|
{
|
|
$this->canvas = imagerotate($this->canvas, $angle, $this->allocate($spaceColor));
|
|
|
|
if( $spaceColor === 'transparent' )
|
|
{
|
|
$this->saveAlpha();
|
|
}
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Set scale
|
|
*
|
|
* @param int $width
|
|
* @param int $height = -1
|
|
* @param string $method = 'bilinearFixed'
|
|
*
|
|
* @return GD
|
|
*/
|
|
public function scale(int $width, int $height = -1, string $mode = 'bilinearFixed') : GD
|
|
{
|
|
$this->canvas = imagescale($this->canvas, $width, $height, Helper::toConstant($mode, 'IMG_'));
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Set interpolation
|
|
*
|
|
* @param string $method = 'bilinearFixed'
|
|
*
|
|
* @return GD
|
|
*/
|
|
public function interpolation(string $method = 'bilinearFixed') : GD
|
|
{
|
|
imagesetinterpolation($this->canvas, Helper::toConstant($method, 'IMG_'));
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Set pixed
|
|
*
|
|
* @param array $settings = []
|
|
*
|
|
* @return GD
|
|
*/
|
|
public function pixel(array $settings = []) : GD
|
|
{
|
|
$x = $settings['x'] ?? $this->x ?? 0;
|
|
$y = $settings['y'] ?? $this->y ?? 0;
|
|
$rgb = $settings['color'] ?? $this->color ?? '0|0|0';
|
|
|
|
imagesetpixel($this->canvas, $x, $y, $this->allocate($rgb));
|
|
|
|
$this->defaultRevolvingVariables(['x', 'y', 'color']);
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Set thickness
|
|
*
|
|
* @param int $thickness = 1
|
|
*
|
|
* @return GD
|
|
*/
|
|
public function thickness(int $thickness = 1) : GD
|
|
{
|
|
imagesetthickness($this->canvas, $thickness);
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Set layer effect
|
|
*
|
|
* @param string $effect = 'normal'
|
|
*
|
|
* @return GD
|
|
*/
|
|
public function layerEffect(string $effect = 'normal') : GD
|
|
{
|
|
imagelayereffect($this->canvas, Helper::toConstant($effect, 'IMG_EFFECT_'));
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Generate Image
|
|
*
|
|
* @param string $type = NULL
|
|
* @param string $save = NULL
|
|
*
|
|
* @return resource
|
|
*/
|
|
public function generate(?string $type = NULL, ?string $save = NULL)
|
|
{
|
|
$canvas = $this->canvas;
|
|
|
|
if( ! empty($type) )
|
|
{
|
|
$this->type = $type;
|
|
}
|
|
|
|
if( ! empty($save) )
|
|
{
|
|
$this->save = $save;
|
|
}
|
|
|
|
if( empty($this->save) && $this->output === true )
|
|
{
|
|
$this->getImageContent();
|
|
}
|
|
|
|
$this->generateImageType();
|
|
$this->destroyImage();
|
|
$this->defaultGlobalVariables();
|
|
|
|
return $canvas;
|
|
}
|
|
|
|
/**
|
|
* Protected create image canvas
|
|
*/
|
|
protected function createImageCanvas($image, $width, $height)
|
|
{
|
|
$this->mimeType = $this->mime->type($image, 1);
|
|
|
|
$this->imageSize = ! isset($width) ? getimagesize($image) : [(int) $width, (int) $height];
|
|
|
|
$this->canvas = $this->createFrom($image);
|
|
}
|
|
|
|
/**
|
|
* Protected create empty canvas
|
|
*/
|
|
protected function createEmptyCanvas($width, $height, $rgb, $real)
|
|
{
|
|
$this->imageSize = [$width, $height];
|
|
|
|
if( $real === false )
|
|
{
|
|
$this->canvas = imagecreate($width, $height);
|
|
}
|
|
else
|
|
{
|
|
$this->canvas = imagecreatetruecolor($width, $height);
|
|
}
|
|
|
|
if( ! empty($rgb) )
|
|
{
|
|
$this->allocate($rgb);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Protected align image watermark
|
|
*/
|
|
protected function alignImageWatermark($source)
|
|
{
|
|
if( is_string($this->target ?? NULL) )
|
|
{
|
|
$size = getimagesize($source);
|
|
|
|
$this->width = $this->width ?? $size[0];
|
|
$this->height = $this->height ?? $size[1];
|
|
|
|
$return = WatermarkImageAligner::align($this->target, $this->width, $this->height, $this->imageSize[0], $this->imageSize[1], $this->margin ?? 0);
|
|
|
|
$this->target = $return;
|
|
|
|
if( isset($this->x) ) $this->source[0] = $this->x;
|
|
if( isset($this->y) ) $this->source[1] = $this->y;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Protected Allocate
|
|
*/
|
|
protected function allocate($rgb)
|
|
{
|
|
$rgb = explode('|', ColorConverter::run($rgb));
|
|
|
|
$red = $rgb[0] ?? 0;
|
|
$green = $rgb[1] ?? 0;
|
|
$blue = $rgb[2] ?? 0;
|
|
$alpha = $rgb[3] ?? 0;
|
|
|
|
return imagecolorallocatealpha($this->canvas, $red, $green, $blue, $alpha);
|
|
}
|
|
|
|
/**
|
|
* Protected Destroy
|
|
*/
|
|
protected function destroyImage()
|
|
{
|
|
imagedestroy($this->canvas);
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Protected Content
|
|
*/
|
|
protected function getImageContent()
|
|
{
|
|
header("Content-type: image/" . ($this->mimeType ?? 'jpeg') );
|
|
}
|
|
|
|
/**
|
|
* Protected Default Variables
|
|
*/
|
|
protected function defaultGlobalVariables()
|
|
{
|
|
$this->canvas = NULL;
|
|
$this->save = NULL;
|
|
$this->output = true;
|
|
$this->quality = NULL;
|
|
$this->type = NULL;
|
|
$this->imageSize = NULL;
|
|
}
|
|
|
|
/**
|
|
* Protected Types
|
|
*/
|
|
protected function generateImageType()
|
|
{
|
|
$type = strtolower($this->type ?? 'jpeg');
|
|
|
|
if( ! empty($this->save) )
|
|
{
|
|
$save = Base::suffix($this->save, '.'.($type === 'jpeg' ? 'jpg' : $type));
|
|
}
|
|
else
|
|
{
|
|
$save = NULL;
|
|
}
|
|
|
|
$function = 'image' . $type;
|
|
|
|
$function($this->canvas, $save, $this->quality ?? ($type === 'png' ? 8 : 80));
|
|
|
|
return $this;
|
|
}
|
|
}
|