113 lines
2.9 KiB
PHP
113 lines
2.9 KiB
PHP
|
<?php
|
||
|
namespace Misuzu\Imaging;
|
||
|
|
||
|
use InvalidArgumentException;
|
||
|
|
||
|
final class GdImage extends Image {
|
||
|
private $gd;
|
||
|
private int $type;
|
||
|
|
||
|
private const CONSTRUCTORS = [
|
||
|
IMAGETYPE_GIF => 'imagecreatefromgif',
|
||
|
IMAGETYPE_JPEG => 'imagecreatefromjpeg',
|
||
|
IMAGETYPE_PNG => 'imagecreatefrompng',
|
||
|
IMAGETYPE_BMP => 'imagecreatefrombmp',
|
||
|
IMAGETYPE_WBMP => 'imagecreatefromwbmp',
|
||
|
IMAGETYPE_WEBP => 'imagecreatefromwebp',
|
||
|
];
|
||
|
|
||
|
private const SAVERS = [
|
||
|
IMAGETYPE_GIF => 'imagegif',
|
||
|
IMAGETYPE_JPEG => 'imagejpeg',
|
||
|
IMAGETYPE_PNG => 'imagepng',
|
||
|
IMAGETYPE_BMP => 'imagebmp',
|
||
|
IMAGETYPE_WBMP => 'imagewbmp',
|
||
|
IMAGETYPE_WEBP => 'imagewebp',
|
||
|
];
|
||
|
|
||
|
public function __construct($pathOrWidth, int $height = -1) {
|
||
|
parent::__construct($pathOrWidth);
|
||
|
|
||
|
if(is_int($pathOrWidth)) {
|
||
|
$this->gd = imagecreatetruecolor($pathOrWidth, $height < 1 ? $pathOrWidth : $height);
|
||
|
$this->type = IMAGETYPE_PNG;
|
||
|
} elseif(is_string($pathOrWidth)) {
|
||
|
$imageInfo = getimagesize($pathOrWidth);
|
||
|
|
||
|
if($imageInfo !== false) {
|
||
|
$this->type = $imageInfo[2];
|
||
|
|
||
|
if(isset(self::CONSTRUCTORS[$this->type]))
|
||
|
$this->gd = self::CONSTRUCTORS[$this->type]($pathOrWidth);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if(!isset($this->gd)) {
|
||
|
throw new InvalidArgumentException('Unsupported image format.');
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public function __destruct() {
|
||
|
if(isset($this->gd))
|
||
|
$this->destroy();
|
||
|
}
|
||
|
|
||
|
public function getWidth(): int {
|
||
|
return imagesx($this->gd);
|
||
|
}
|
||
|
|
||
|
public function getHeight(): int {
|
||
|
return imagesy($this->gd);
|
||
|
}
|
||
|
|
||
|
public function hasFrames(): bool {
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
public function next(): bool {
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
public function resize(int $width, int $height): bool {
|
||
|
$resized = imagescale($this->gd, $width, $height, IMG_BICUBIC_FIXED);
|
||
|
|
||
|
if($resized === false)
|
||
|
return false;
|
||
|
|
||
|
imagedestroy($this->gd);
|
||
|
$this->gd = $resized;
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
public function crop(int $width, int $height, int $x, int $y): bool {
|
||
|
$cropped = imagecrop($this->gd, compact('width', 'height', 'x', 'y'));
|
||
|
|
||
|
if($cropped === false)
|
||
|
return false;
|
||
|
|
||
|
imagedestroy($this->gd);
|
||
|
$this->gd = $cropped;
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
public function setPage(int $width, int $height, int $x, int $y): bool {
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
public function save(string $path): bool {
|
||
|
if(isset(self::SAVERS[$this->type]))
|
||
|
return self::SAVERS[$this->type]($this->gd, $path);
|
||
|
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
public function destroy(): void {
|
||
|
if(imagedestroy($this->gd)) {
|
||
|
$this->gd = null;
|
||
|
$this->type = 0;
|
||
|
}
|
||
|
}
|
||
|
}
|