|
|
@@ -59,7 +59,7 @@ class OC_Image implements \OCP\IImage { |
|
|
|
// Default quality for webp images |
|
|
|
protected const DEFAULT_WEBP_QUALITY = 80; |
|
|
|
|
|
|
|
/** @var false|resource|\GdImage */ |
|
|
|
/** @var false|\GdImage */ |
|
|
|
protected $resource = false; // tmp resource. |
|
|
|
/** @var int */ |
|
|
|
protected $imageType = IMAGETYPE_PNG; // Default to png if file type isn't evident. |
|
|
@@ -67,20 +67,20 @@ class OC_Image implements \OCP\IImage { |
|
|
|
protected $mimeType = 'image/png'; // Default to png |
|
|
|
/** @var null|string */ |
|
|
|
protected $filePath = null; |
|
|
|
/** @var finfo */ |
|
|
|
private $fileInfo; |
|
|
|
/** @var ?finfo */ |
|
|
|
private $fileInfo = null; |
|
|
|
/** @var \OCP\ILogger */ |
|
|
|
private $logger; |
|
|
|
/** @var \OCP\IConfig */ |
|
|
|
private $config; |
|
|
|
/** @var array */ |
|
|
|
private $exif; |
|
|
|
/** @var ?array */ |
|
|
|
private $exif = null; |
|
|
|
|
|
|
|
/** |
|
|
|
* Constructor. |
|
|
|
* |
|
|
|
* @param resource|string|\GdImage $imageRef The path to a local file, a base64 encoded string or a resource created by |
|
|
|
* an imagecreate* function. |
|
|
|
* @param mixed $imageRef Deprecated, should be null |
|
|
|
* @psalm-assert null $imageRef |
|
|
|
* @param \OCP\ILogger $logger |
|
|
|
* @param \OCP\IConfig $config |
|
|
|
* @throws \InvalidArgumentException in case the $imageRef parameter is not null |
|
|
@@ -107,11 +107,11 @@ class OC_Image implements \OCP\IImage { |
|
|
|
/** |
|
|
|
* Determine whether the object contains an image resource. |
|
|
|
* |
|
|
|
* @psalm-assert-if-true \GdImage $this->resource |
|
|
|
* @return bool |
|
|
|
*/ |
|
|
|
public function valid(): bool { |
|
|
|
if ((is_resource($this->resource) && get_resource_type($this->resource) === 'gd') || |
|
|
|
(is_object($this->resource) && get_class($this->resource) === \GdImage::class)) { |
|
|
|
if (is_object($this->resource) && get_class($this->resource) === \GdImage::class) { |
|
|
|
return true; |
|
|
|
} |
|
|
|
|
|
|
@@ -134,10 +134,7 @@ class OC_Image implements \OCP\IImage { |
|
|
|
*/ |
|
|
|
public function width(): int { |
|
|
|
if ($this->valid()) { |
|
|
|
$width = imagesx($this->resource); |
|
|
|
if ($width !== false) { |
|
|
|
return $width; |
|
|
|
} |
|
|
|
return imagesx($this->resource); |
|
|
|
} |
|
|
|
return -1; |
|
|
|
} |
|
|
@@ -149,10 +146,7 @@ class OC_Image implements \OCP\IImage { |
|
|
|
*/ |
|
|
|
public function height(): int { |
|
|
|
if ($this->valid()) { |
|
|
|
$height = imagesy($this->resource); |
|
|
|
if ($height !== false) { |
|
|
|
return $height; |
|
|
|
} |
|
|
|
return imagesy($this->resource); |
|
|
|
} |
|
|
|
return -1; |
|
|
|
} |
|
|
@@ -338,25 +332,14 @@ class OC_Image implements \OCP\IImage { |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* @param resource|\GdImage $resource |
|
|
|
* @throws \InvalidArgumentException in case the supplied resource does not have the type "gd" |
|
|
|
* @param \GdImage $resource |
|
|
|
*/ |
|
|
|
public function setResource($resource) { |
|
|
|
// For PHP<8 |
|
|
|
if (is_resource($resource) && get_resource_type($resource) === 'gd') { |
|
|
|
$this->resource = $resource; |
|
|
|
return; |
|
|
|
} |
|
|
|
// PHP 8 has real objects for GD stuff |
|
|
|
if (is_object($resource) && get_class($resource) === \GdImage::class) { |
|
|
|
$this->resource = $resource; |
|
|
|
return; |
|
|
|
} |
|
|
|
throw new \InvalidArgumentException('Supplied resource is not of type "gd".'); |
|
|
|
public function setResource(\GdImage $resource): void { |
|
|
|
$this->resource = $resource; |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* @return false|resource|\GdImage Returns the image resource if any |
|
|
|
* @return false|\GdImage Returns the image resource if any |
|
|
|
*/ |
|
|
|
public function resource() { |
|
|
|
return $this->resource; |
|
|
@@ -394,8 +377,7 @@ class OC_Image implements \OCP\IImage { |
|
|
|
$res = imagepng($this->resource); |
|
|
|
break; |
|
|
|
case "image/jpeg": |
|
|
|
/** @psalm-suppress InvalidScalarArgument */ |
|
|
|
imageinterlace($this->resource, (PHP_VERSION_ID >= 80000 ? true : 1)); |
|
|
|
imageinterlace($this->resource, true); |
|
|
|
$quality = $this->getJpegQuality(); |
|
|
|
$res = imagejpeg($this->resource, null, $quality); |
|
|
|
break; |
|
|
@@ -584,7 +566,7 @@ class OC_Image implements \OCP\IImage { |
|
|
|
* It is the responsibility of the caller to position the pointer at the correct place and to close the handle again. |
|
|
|
* |
|
|
|
* @param resource $handle |
|
|
|
* @return resource|\GdImage|false An image resource or false on error |
|
|
|
* @return \GdImage|false An image resource or false on error |
|
|
|
*/ |
|
|
|
public function loadFromFileHandle($handle) { |
|
|
|
$contents = stream_get_contents($handle); |
|
|
@@ -663,7 +645,7 @@ class OC_Image implements \OCP\IImage { |
|
|
|
* Loads an image from a local file. |
|
|
|
* |
|
|
|
* @param bool|string $imagePath The path to a local file. |
|
|
|
* @return bool|resource|\GdImage An image resource or false on error |
|
|
|
* @return bool|\GdImage An image resource or false on error |
|
|
|
*/ |
|
|
|
public function loadFromFile($imagePath = false) { |
|
|
|
// exif_imagetype throws "read error!" if file is less than 12 byte |
|
|
@@ -801,7 +783,7 @@ class OC_Image implements \OCP\IImage { |
|
|
|
* Loads an image from a string of data. |
|
|
|
* |
|
|
|
* @param string $str A string of image data as read from a file. |
|
|
|
* @return bool|resource|\GdImage An image resource or false on error |
|
|
|
* @return bool|\GdImage An image resource or false on error |
|
|
|
*/ |
|
|
|
public function loadFromData(string $str) { |
|
|
|
if (!$this->checkImageDataSize($str)) { |
|
|
@@ -827,7 +809,7 @@ class OC_Image implements \OCP\IImage { |
|
|
|
* Loads an image from a base64 encoded string. |
|
|
|
* |
|
|
|
* @param string $str A string base64 encoded string of image data. |
|
|
|
* @return bool|resource|\GdImage An image resource or false on error |
|
|
|
* @return bool|\GdImage An image resource or false on error |
|
|
|
*/ |
|
|
|
public function loadFromBase64(string $str) { |
|
|
|
$data = base64_decode($str); |
|
|
@@ -868,7 +850,7 @@ class OC_Image implements \OCP\IImage { |
|
|
|
|
|
|
|
/** |
|
|
|
* @param $maxSize |
|
|
|
* @return resource|bool|\GdImage |
|
|
|
* @return bool|\GdImage |
|
|
|
*/ |
|
|
|
private function resizeNew(int $maxSize) { |
|
|
|
if (!$this->valid()) { |
|
|
@@ -909,7 +891,7 @@ class OC_Image implements \OCP\IImage { |
|
|
|
/** |
|
|
|
* @param int $width |
|
|
|
* @param int $height |
|
|
|
* @return resource|bool|\GdImage |
|
|
|
* @return bool|\GdImage |
|
|
|
*/ |
|
|
|
public function preciseResizeNew(int $width, int $height) { |
|
|
|
if (!($width > 0) || !($height > 0)) { |
|
|
@@ -985,13 +967,13 @@ class OC_Image implements \OCP\IImage { |
|
|
|
|
|
|
|
// preserve transparency |
|
|
|
if ($this->imageType == IMAGETYPE_GIF or $this->imageType == IMAGETYPE_PNG) { |
|
|
|
imagecolortransparent($process, imagecolorallocatealpha($process, 0, 0, 0, 127)); |
|
|
|
imagecolortransparent($process, imagecolorallocatealpha($process, 0, 0, 0, 127) ?: null); |
|
|
|
imagealphablending($process, false); |
|
|
|
imagesavealpha($process, true); |
|
|
|
} |
|
|
|
|
|
|
|
imagecopyresampled($process, $this->resource, 0, 0, $x, $y, $targetWidth, $targetHeight, $width, $height); |
|
|
|
if ($process === false) { |
|
|
|
$result = imagecopyresampled($process, $this->resource, 0, 0, $x, $y, $targetWidth, $targetHeight, $width, $height); |
|
|
|
if ($result === false) { |
|
|
|
$this->logger->debug('OC_Image->centerCrop, Error re-sampling process image ' . $width . 'x' . $height, ['app' => 'core']); |
|
|
|
return false; |
|
|
|
} |
|
|
@@ -1027,7 +1009,7 @@ class OC_Image implements \OCP\IImage { |
|
|
|
* @param int $y Vertical position |
|
|
|
* @param int $w Width |
|
|
|
* @param int $h Height |
|
|
|
* @return resource|\GdImage|false |
|
|
|
* @return \GdImage|false |
|
|
|
*/ |
|
|
|
public function cropNew(int $x, int $y, int $w, int $h) { |
|
|
|
if (!$this->valid()) { |
|
|
@@ -1042,13 +1024,13 @@ class OC_Image implements \OCP\IImage { |
|
|
|
|
|
|
|
// preserve transparency |
|
|
|
if ($this->imageType == IMAGETYPE_GIF or $this->imageType == IMAGETYPE_PNG) { |
|
|
|
imagecolortransparent($process, imagecolorallocatealpha($process, 0, 0, 0, 127)); |
|
|
|
imagecolortransparent($process, imagecolorallocatealpha($process, 0, 0, 0, 127) ?: null); |
|
|
|
imagealphablending($process, false); |
|
|
|
imagesavealpha($process, true); |
|
|
|
} |
|
|
|
|
|
|
|
imagecopyresampled($process, $this->resource, 0, 0, $x, $y, $w, $h, $w, $h); |
|
|
|
if ($process === false) { |
|
|
|
$result = imagecopyresampled($process, $this->resource, 0, 0, $x, $y, $w, $h, $w, $h); |
|
|
|
if ($result === false) { |
|
|
|
$this->logger->debug(__METHOD__ . '(): Error re-sampling process image ' . $w . 'x' . $h, ['app' => 'core']); |
|
|
|
return false; |
|
|
|
} |