Skip to content

Commit ac93230

Browse files
authored
Merge pull request #10827 from steiny2k/HEICHEIF
HEIC previews as JPG rather than PNGs to save space.
2 parents c850b3a + 4758942 commit ac93230

File tree

1 file changed

+104
-4
lines changed

1 file changed

+104
-4
lines changed

lib/private/Preview/HEIC.php

Lines changed: 104 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
<?php
2+
declare(strict_types=1);
23
/**
34
* @author Thomas Müller <thomas.mueller@tmit.eu>
45
*
@@ -22,19 +23,118 @@
2223

2324
namespace OC\Preview;
2425

25-
class HEIC extends Bitmap {
26+
use OCP\ILogger;
27+
28+
/**
29+
* Creates a JPG preview using ImageMagick via the PECL extension
30+
*
31+
* @package OC\Preview
32+
*/
33+
class HEIC extends Provider {
2634
/**
2735
* {@inheritDoc}
2836
*/
29-
public function getMimeType() {
37+
public function getMimeType(): string {
3038
return '/image\/hei(f|c)/';
3139
}
3240

3341
/**
3442
* {@inheritDoc}
3543
*/
36-
public function isAvailable(\OCP\Files\FileInfo $file) {
37-
return in_array("HEIC", \Imagick::queryFonts("HEI*") );
44+
public function isAvailable(\OCP\Files\FileInfo $file): bool {
45+
return in_array('HEIC', \Imagick::queryFormats("HEI*"));
46+
}
47+
48+
/**
49+
* {@inheritDoc}
50+
*/
51+
public function getThumbnail($path, $maxX, $maxY, $scalingup, $fileview) {
52+
$tmpPath = $fileview->toTmpFile($path);
53+
if (!$tmpPath) {
54+
return false;
55+
}
56+
57+
// Creates \Imagick object from the heic file
58+
try {
59+
$bp = $this->getResizedPreview($tmpPath, $maxX, $maxY);
60+
$bp->setFormat('jpg');
61+
} catch (\Exception $e) {
62+
\OC::$server->getLogger()->logException($e, [
63+
'message' => 'File: ' . $fileview->getAbsolutePath($path) . ' Imagick says:',
64+
'level' => ILogger::ERROR,
65+
'app' => 'core',
66+
]);
67+
return false;
68+
}
69+
70+
unlink($tmpPath);
71+
72+
//new bitmap image object
73+
$image = new \OC_Image();
74+
$image->loadFromData($bp);
75+
//check if image object is valid
76+
return $image->valid() ? $image : false;
77+
}
78+
79+
/**
80+
* Returns a preview of maxX times maxY dimensions in JPG format
81+
*
82+
* * The default resolution is already 72dpi, no need to change it for a bitmap output
83+
* * It's possible to have proper colour conversion using profileimage().
84+
* ICC profiles are here: http://www.color.org/srgbprofiles.xalter
85+
* * It's possible to Gamma-correct an image via gammaImage()
86+
*
87+
* @param string $tmpPath the location of the file to convert
88+
* @param int $maxX
89+
* @param int $maxY
90+
*
91+
* @return \Imagick
92+
*/
93+
private function getResizedPreview($tmpPath, $maxX, $maxY) {
94+
$bp = new \Imagick();
95+
96+
// Layer 0 contains either the bitmap or a flat representation of all vector layers
97+
$bp->readImage($tmpPath . '[0]');
98+
99+
$bp->setImageFormat('jpg');
100+
101+
$bp = $this->resize($bp, $maxX, $maxY);
102+
103+
return $bp;
104+
}
105+
106+
/**
107+
* Returns a resized \Imagick object
108+
*
109+
* If you want to know more on the various methods available to resize an
110+
* image, check out this link : @link https://stackoverflow.com/questions/8517304/what-the-difference-of-sample-resample-scale-resize-adaptive-resize-thumbnail-im
111+
*
112+
* @param \Imagick $bp
113+
* @param int $maxX
114+
* @param int $maxY
115+
*
116+
* @return \Imagick
117+
*/
118+
private function resize($bp, $maxX, $maxY) {
119+
list($previewWidth, $previewHeight) = array_values($bp->getImageGeometry());
120+
121+
// We only need to resize a preview which doesn't fit in the maximum dimensions
122+
if ($previewWidth > $maxX || $previewHeight > $maxY) {
123+
// If we want a small image (thumbnail) let's be most space- and time-efficient
124+
if ($maxX <= 500 && $maxY <= 500) {
125+
$bp->thumbnailImage($maxY, $maxX, true);
126+
$bp->stripImage();
127+
} else {
128+
// A bigger image calls for some better resizing algorithm
129+
// According to http://www.imagemagick.org/Usage/filter/#lanczos
130+
// the catrom filter is almost identical to Lanczos2, but according
131+
// to http://php.net/manual/en/imagick.resizeimage.php it is
132+
// significantly faster
133+
$bp->resizeImage($maxX, $maxY, \Imagick::FILTER_CATROM, 1, true);
134+
}
135+
}
136+
137+
return $bp;
38138
}
39139

40140
}

0 commit comments

Comments
 (0)