getLocalFile($file); if ($tmpPath === false) { \OC::$server->get(LoggerInterface::class)->error( 'Failed to get thumbnail for: ' . $file->getPath(), ['app' => 'core'] ); return null; } // Creates \Imagick object from bitmap or vector file try { $bp = $this->getResizedPreview($tmpPath, $maxX, $maxY); } catch (\Exception $e) { \OC::$server->get(LoggerInterface::class)->info( 'File: ' . $file->getPath() . ' Imagick says:', [ 'exception' => $e, 'app' => 'core', ] ); return null; } $this->cleanTmpFiles(); //new bitmap image object $image = new \OCP\Image(); $image->loadFromData((string)$bp); //check if image object is valid return $image->valid() ? $image : null; } /** * Returns a preview of maxX times maxY dimensions in PNG format * * * The default resolution is already 72dpi, no need to change it for a bitmap output * * It's possible to have proper colour conversion using profileimage(). * ICC profiles are here: http://www.color.org/srgbprofiles.xalter * * It's possible to Gamma-correct an image via gammaImage() * * @param string $tmpPath the location of the file to convert * @param int $maxX * @param int $maxY * * @return \Imagick * * @throws \Exception */ private function getResizedPreview($tmpPath, $maxX, $maxY) { $bp = new Imagick(); // Validate mime type $bp->pingImage($tmpPath . '[0]'); $mimeType = $bp->getImageMimeType(); if (!preg_match($this->getAllowedMimeTypes(), $mimeType)) { throw new \Exception('File mime type does not match the preview provider: ' . $mimeType); } // Layer 0 contains either the bitmap or a flat representation of all vector layers $bp->readImage($tmpPath . '[0]'); $bp = $this->resize($bp, $maxX, $maxY); $bp->setImageFormat('png'); return $bp; } /** * Returns a resized \Imagick object * * If you want to know more on the various methods available to resize an * image, check out this link : @link https://stackoverflow.com/questions/8517304/what-the-difference-of-sample-resample-scale-resize-adaptive-resize-thumbnail-im * * @param \Imagick $bp * @param int $maxX * @param int $maxY * * @return \Imagick */ private function resize($bp, $maxX, $maxY) { [$previewWidth, $previewHeight] = array_values($bp->getImageGeometry()); // We only need to resize a preview which doesn't fit in the maximum dimensions if ($previewWidth > $maxX || $previewHeight > $maxY) { // TODO: LANCZOS is the default filter, CATROM could bring similar results faster $bp->resizeImage($maxX, $maxY, imagick::FILTER_LANCZOS, 1, true); } return $bp; } }