Skip to content

Commit 819a5c7

Browse files
committed
Add ImageMagick support
This adds support for image types like heic, tiff, and many more without the need for hosting imaginary application. This is a basic implementation that lacks extended mimetype checking.
1 parent 2ff87d2 commit 819a5c7

File tree

1 file changed

+88
-2
lines changed

1 file changed

+88
-2
lines changed

lib/Helper/TempImage.php

Lines changed: 88 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ private function prepareImage() {
139139

140140
$this->ratio = 1 / $scaleFactor;
141141
}
142-
else {
142+
elseif (($imagetype = exif_imagetype($this->imagePath)) !== false and $this->isImageTypeSupportedByGD($imagetype)) {
143143
$this->loadFromFile($this->imagePath);
144144
$this->fixOrientation();
145145

@@ -155,6 +155,46 @@ private function prepareImage() {
155155

156156
$this->ratio = $this->resizeOCImage();
157157
}
158+
elseif (extension_loaded('imagick')) {
159+
try {
160+
$imagick = new \Imagick($this->imagePath . '[0]');
161+
$imagick->autoOrient();
162+
163+
$geometry = $imagick->getImageGeometry();
164+
$widthOrig = $geometry['width'];
165+
$heightOrig = $geometry['height'];
166+
if (($widthOrig < $this->minImageSide) ||
167+
($heightOrig < $this->minImageSide)) {
168+
$this->skipped = true;
169+
return;
170+
}
171+
172+
$scaleFactor = $this->getResizeRatio($widthOrig, $heightOrig);
173+
174+
$newWidth = intval(round($widthOrig * $scaleFactor));
175+
$newHeight = intval(round($heightOrig * $scaleFactor));
176+
177+
# According to https://usage.imagemagick.org/filter the 'Catrom'
178+
# filter, is almost an exact duplicate of the 'Lanczos2' filter
179+
# though it is much faster to generate mathematically.
180+
$imagick->resizeImage($newWidth, $newHeight, \Imagick::FILTER_CATROM, 1, true);
181+
182+
$imagick->setImageFormat(str_replace('image/', '', $this->preferredMimeType));
183+
$this->loadFromData($imagick->getImageBlob());
184+
} catch (\ImagickException $e) {
185+
throw new \RuntimeException("Imagick processing error: " . $e->getMessage());
186+
}
187+
188+
if (!$this->valid()) {
189+
throw new \RuntimeException("Imagick image is not valid.");
190+
}
191+
192+
$this->ratio = 1 / $scaleFactor;
193+
}
194+
else {
195+
throw new \RuntimeException("Local image could not be processed, probably unsupported format");
196+
}
197+
158198

159199
$this->tempPath = $this->tempManager->getTemporaryFile();
160200
$this->save($this->tempPath, $this->preferredMimeType);
@@ -198,4 +238,50 @@ private function getResizeRatio($widthOrig, $heightOrig): float {
198238
return sqrt($areaRatio);
199239
}
200240

201-
}
241+
/**
242+
* Check if image type is supported by this PHP build
243+
*
244+
* @return bool Returns true if the image type is supported by the
245+
* version of GD linked into PHP.
246+
*/
247+
private function isImageTypeSupportedByGD(int $imagetype): bool {
248+
if ($imagetype === IMAGETYPE_GIF) {
249+
return (imagetypes() & IMG_GIF) === IMG_GIF;
250+
} elseif ($imagetype === IMAGETYPE_JPEG) {
251+
return (imagetypes() & IMG_JPG) === IMG_JPG;
252+
} elseif ($imagetype === IMAGETYPE_PNG) {
253+
return (imagetypes() & IMG_PNG) === IMG_PNG;
254+
} elseif ($imagetype === IMAGETYPE_WBMP) {
255+
return (imagetypes() & IMG_WBMP) === IMG_WBMP;
256+
} elseif ($imagetype === IMAGETYPE_XBM) {
257+
return (imagetypes() & IMG_XPM) === IMG_XPM;
258+
} elseif ($imagetype === IMAGETYPE_WEBP) {
259+
return (imagetypes() & IMG_WEBP) === IMG_WEBP;
260+
} elseif ($imagetype === IMAGETYPE_BMP) {
261+
return (imagetypes() & IMG_BMP) === IMG_BMP;
262+
} elseif(PHP_VERSION_ID >= 80100 and $imagetype === IMAGETYPE_AVIF) {
263+
return (imagetypes() & IMG_AVIF) === IMG_AVIF;
264+
} else {
265+
return false;
266+
}
267+
}
268+
}
269+
270+
271+
if (!function_exists('exif_imagetype')) {
272+
/**
273+
* Workaround if exif_imagetype does not exist
274+
*
275+
* Copied from https://github.com/nextcloud/server/blob/master/lib/private/Image.php
276+
*
277+
* @link https://www.php.net/manual/en/function.exif-imagetype.php#80383
278+
* @param string $fileName
279+
* @return int|false
280+
*/
281+
function exif_imagetype(string $fileName) {
282+
if (($info = getimagesize($fileName)) !== false) {
283+
return $info[2];
284+
}
285+
return false;
286+
}
287+
}

0 commit comments

Comments
 (0)