VvebOIDC/system/media/imagick.php

177 lines
4.4 KiB
PHP

<?php
/**
* Vvveb
*
* Copyright (C) 2022 Ziadin Givan
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
namespace Vvveb\System\Media;
class Image {
private $file;
private $image;
private $width;
private $height;
private $mime;
public function __construct($file) {
if (file_exists($file)) {
$this->file = $file;
$this->image = new \Imagick();
$this->image->readImage($file);
$this->width = $this->image->getImageWidth();
$this->height = $this->image->getImageHeight();
$this->mime = $this->image->getFormat();
//if (STRIP_EXIF) {
$profiles = $this->image->getImageProfiles('icc', true);
$this->image->stripImage();
if (! empty($profiles)) {
$this->image->profileImage('icc', $profiles['icc']);
}
//}
} else {
//throw new \Exception("Could not load image $file");
}
}
public function getFile() {
return $this->file;
}
public function getImage() {
return $this->image;
}
public function getWidth() {
return $this->width;
}
public function getHeight() {
return $this->height;
}
public function getMime() {
return $this->mime;
}
public function save($file, $quality = 80, $extension = false) {
if (! $this->image) {
return;
}
$this->image->setImageFormat($extension ?: $this->mime);
$this->image->setCompressionQuality($quality);
//$this->image->setImageCompressionQuality($quality);
$this->image->stripImage();
return @$this->image->writeImage($file);
}
public function resize($width, $height = 0, $method = 's') {
if (! $this->width || ! $this->height) {
return;
}
switch ($method) {
case 's':
return $this->stretch($width, $height);
case 'c':
return $this->crop($width, $height);
case 'cs':
return $this->cropsize($width, $height);
}
}
public function stretch($width, $height = 0) {
//$this->width = $this->image->getImageWidth();
//$this->height = $this->image->getImageHeight();
if ($width && $height) {
$scaleW = $width / $this->width;
$scaleH = $height / $this->height;
$scale = min($scaleW, $scaleH);
$width = (int)($this->width * $scale);
$height = (int)($this->height * $scale);
} else {
if ($width) {
$height = ceil($this->height / ($this->width / $width));
} else {
if ($height) {
$width = ceil($this->width / ($this->height / $height));
}
}
}
if (method_exists($this->image, 'adaptiveResizeImage')) {
return $this->image->adaptiveResizeImage($width, $height);
} else {
//$this->image->thumbnailImage($width, $height, true, true);
return $this->image->resizeImage($width, $height, \Imagick::FILTER_LANCZOS, 1, true);
}
}
public function crop($top_x, $top_y, $bottom_x, $bottom_y) {
$this->image->cropImage($bottom_x - $top_x, $bottom_y - $top_y, $top_x, $top_y);
$this->width = $this->image->getImageWidth();
$this->height = $this->image->getImageHeight();
}
public function cropsize($width, $height = 0) {
$width = $width ?: $height;
$height = $height ?: $width;
$newRatio = $width / $height;
$ratio = $this->width / $this->height;
if ($newRatio > $ratio) {
$new_width = $width;
$new_height = floor($width / $this->width * $this->height);
$crop_x = 0;
$crop_y = intval(($new_height - $height) / 2);
} else {
$new_width = floor($height / $this->height * $this->width);
$new_height = $height;
$crop_x = intval(($new_width - $width) / 2);
$crop_y = 0;
}
$this->image->resizeImage($new_width, $new_height, \Imagick::FILTER_LANCZOS, 1, true);
$this->image->cropImage($width, $height, $crop_x, $crop_y);
}
public static function formats($format = false) {
$formats = \Imagick::queryformats() ?? [];
//return array_map(fn($value) => strtolower($value), $info);
return array_map('strtolower', $formats);
}
}