Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
108 changes: 104 additions & 4 deletions lib/private/Preview/HEIC.php
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
<?php
declare(strict_types=1);
/**
* @author Thomas Müller <[email protected]>
*
Expand All @@ -22,19 +23,118 @@

namespace OC\Preview;

class HEIC extends Bitmap {
use OCP\ILogger;

/**
* Creates a JPG preview using ImageMagick via the PECL extension
*
* @package OC\Preview
*/
class HEIC extends Provider {
/**
* {@inheritDoc}
*/
public function getMimeType() {
public function getMimeType(): string {
return '/image\/hei(f|c)/';
}

/**
* {@inheritDoc}
*/
public function isAvailable(\OCP\Files\FileInfo $file) {
return in_array("HEIC", \Imagick::queryFonts("HEI*") );
public function isAvailable(\OCP\Files\FileInfo $file): bool {
return in_array('HEIC', \Imagick::queryFormats("HEI*"));
}

/**
* {@inheritDoc}
*/
public function getThumbnail($path, $maxX, $maxY, $scalingup, $fileview) {
$tmpPath = $fileview->toTmpFile($path);
if (!$tmpPath) {
return false;
}

// Creates \Imagick object from the heic file
try {
$bp = $this->getResizedPreview($tmpPath, $maxX, $maxY);
$bp->setFormat('jpg');
} catch (\Exception $e) {
\OC::$server->getLogger()->logException($e, [
'message' => 'File: ' . $fileview->getAbsolutePath($path) . ' Imagick says:',
'level' => ILogger::ERROR,
'app' => 'core',
]);
return false;
}

unlink($tmpPath);

//new bitmap image object
$image = new \OC_Image();
$image->loadFromData($bp);
//check if image object is valid
return $image->valid() ? $image : false;
}

/**
* Returns a preview of maxX times maxY dimensions in JPG 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
*/
private function getResizedPreview($tmpPath, $maxX, $maxY) {
$bp = new \Imagick();

// Layer 0 contains either the bitmap or a flat representation of all vector layers
$bp->readImage($tmpPath . '[0]');

$bp->setImageFormat('jpg');

$bp = $this->resize($bp, $maxX, $maxY);

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) {
list($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) {
// If we want a small image (thumbnail) let's be most space- and time-efficient
if ($maxX <= 500 && $maxY <= 500) {
$bp->thumbnailImage($maxY, $maxX, true);
$bp->stripImage();
} else {
// A bigger image calls for some better resizing algorithm
// According to http://www.imagemagick.org/Usage/filter/#lanczos
// the catrom filter is almost identical to Lanczos2, but according
// to http://php.net/manual/en/imagick.resizeimage.php it is
// significantly faster
$bp->resizeImage($maxX, $maxY, \Imagick::FILTER_CATROM, 1, true);
}
}

return $bp;
}

}