@@ -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