diff --git a/lib/Classifiers/Classifier.php b/lib/Classifiers/Classifier.php index a76631c5..e13b00e2 100644 --- a/lib/Classifiers/Classifier.php +++ b/lib/Classifiers/Classifier.php @@ -261,54 +261,111 @@ private function getConvertedFilePath(Node $file): string { return $path; } - // Create a temporary file *with the correct extension* - $tmpname = $this->tempManager->getTemporaryFile('.jpg'); - - if (!$this->previewProvider->isAvailable($file) && !($file instanceof File)) { - return $path; - } - try { $this->logger->debug('generating preview of ' . $file->getId() . ' with dimension '.self::TEMP_FILE_DIMENSION); - $image = $this->previewProvider->getPreview($file, self::TEMP_FILE_DIMENSION, self::TEMP_FILE_DIMENSION); + + $imageType = exif_imagetype($path); //To troubleshoot console errors, GD does not support all formats. + if (0 < $imageType && $this->config->getSystemValueString('recognize.preview.gd', 'true') === 'true') { + return $this->generatePrevieWithGD($path); + } else { + if (!$this->previewProvider->isAvailable($file)) { + return $path; + } + return $this->generatePreviewWithProvider($file); + } } catch(\Throwable $e) { - $this->logger->info('Failed to generate preview of ' . $file->getId() . ' with dimension '.self::TEMP_FILE_DIMENSION . ': ' . $e->getMessage()); + $this->logger->warning('Failed to generate preview of ' . $file->getId() . ' with dimension '.self::TEMP_FILE_DIMENSION . ': ' . $e->getMessage()); return $path; } + } - $tmpfile = fopen($tmpname, 'wb'); + public function cleanUpTmpFiles():void { + $this->tempManager->clean(); + } - if ($tmpfile === false) { - $this->logger->warning('Could not open tmpfile'); - return $path; - } + /** + * @param File $file + * @return string + * @throws \OCA\Recognize\Exception\Exception|NotFoundException + */ + public function generatePreviewWithProvider(File $file): string { + $image = $this->previewProvider->getPreview($file, self::TEMP_FILE_DIMENSION, self::TEMP_FILE_DIMENSION); try { $preview = $image->read(); } catch (NotPermittedException $e) { - $this->logger->warning('Could not read preview file', ['exception' => $e]); - return $path; + throw new \OCA\Recognize\Exception\Exception('Could not read preview file', 0, $e); } if ($preview === false) { - $this->logger->warning('Could not open preview file'); - return $path; + throw new \OCA\Recognize\Exception\Exception('Could not open preview file'); } - $this->logger->debug('Copying ' . $file->getId() . ' preview to tempfolder'); - if (stream_copy_to_stream($preview, $tmpfile) === false) { - $this->logger->warning('Could not copy preview file to temp folder'); - fclose($preview); - fclose($tmpfile); - return $path; + // Create a temporary file *with the correct extension* + $tmpname = $this->tempManager->getTemporaryFile('.jpg'); + + $tmpfile = fopen($tmpname, 'wb'); + + if ($tmpfile === false) { + throw new \OCA\Recognize\Exception\Exception('Could not open tmpfile'); } + + $copyResult = stream_copy_to_stream($preview, $tmpfile); fclose($preview); fclose($tmpfile); + if ($copyResult === false) { + throw new \OCA\Recognize\Exception\Exception('Could not copy preview file to temp folder'); + } + + $imagetype = exif_imagetype($tmpname); + + if (in_array($imagetype, [IMAGETYPE_WEBP, IMAGETYPE_AVIF, false])) { // To troubleshoot if it is a webp or avif. + $previewImage = imagecreatefromstring(file_get_contents($tmpname)); + $use_gd_quality = (int)$this->config->getSystemValue('recognize.preview.quality', '100'); + if (imagejpeg($previewImage, $tmpname, $use_gd_quality) === false) { + throw new \OCA\Recognize\Exception\Exception('Could not copy preview file to temp folder'); + } + } + return $tmpname; } - public function cleanUpTmpFiles():void { - $this->tempManager->clean(); + /** + * @param string $path + * @return string + * @throws \OCA\Recognize\Exception\Exception + */ + public function generatePrevieWithGD(string $path): string { + $image = imagecreatefromstring(file_get_contents($path)); + $width = imagesx($image); + $height = imagesy($image); + + $maxWidth = self::TEMP_FILE_DIMENSION; + $maxHeight = self::TEMP_FILE_DIMENSION; + + if ($width > $maxWidth || $height > $maxHeight) { + $aspectRatio = $width / $height; + if ($width > $height) { + $newWidth = $maxWidth; + $newHeight = $maxWidth / $aspectRatio; + } else { + $newHeight = $maxHeight; + $newWidth = $maxHeight * $aspectRatio; + } + $previewImage = imagescale($image, (int)$newWidth, (int)$newHeight); + } else { + return $path; + } + + // Create a temporary file *with the correct extension* + $tmpname = $this->tempManager->getTemporaryFile('.jpg'); + + $use_gd_quality = (int)$this->config->getSystemValue('recognize.preview.quality', '100'); + if (imagejpeg($previewImage, $tmpname, $use_gd_quality) === false) { + throw new \OCA\Recognize\Exception\Exception('Could not copy preview file to temp folder'); + } + + return $tmpname; } }