diff --git a/core/ajax/preview.php b/core/ajax/preview.php index fc98d80eb0..baa0ed4ec6 100644 --- a/core/ajax/preview.php +++ b/core/ajax/preview.php @@ -31,6 +31,7 @@ $maxY = array_key_exists('y', $_GET) ? (int)$_GET['y'] : '36'; $scalingUp = array_key_exists('scalingup', $_GET) ? (bool)$_GET['scalingup'] : true; $keepAspect = array_key_exists('a', $_GET) ? true : false; $always = array_key_exists('forceIcon', $_GET) ? (bool)$_GET['forceIcon'] : true; +$mode = array_key_exists('mode', $_GET) ? $_GET['mode'] : 'fill'; if ($file === '') { //400 Bad Request @@ -56,6 +57,7 @@ if (!$info instanceof OCP\Files\FileInfo || !$always && !\OC::$server->getPrevie $preview->setMaxX($maxX); $preview->setMaxY($maxY); $preview->setScalingUp($scalingUp); + $preview->setMode($mode); $preview->setKeepAspect($keepAspect); $preview->showPreview(); } diff --git a/lib/private/preview.php b/lib/private/preview.php index 5dcab476a4..978da1161c 100644 --- a/lib/private/preview.php +++ b/lib/private/preview.php @@ -38,6 +38,9 @@ class Preview { //the thumbnail folder const THUMBNAILS_FOLDER = 'thumbnails'; + const MODE_FILL = 'fill'; + const MODE_COVER = 'cover'; + //config private $maxScaleFactor; /** @var int maximum width allowed for a preview */ @@ -56,6 +59,7 @@ class Preview { private $scalingUp; private $mimeType; private $keepAspect = false; + private $mode = self::MODE_FILL; //used to calculate the size of the preview to generate /** @var int $maxPreviewWidth max width a preview can have */ @@ -331,6 +335,19 @@ class Preview { return $this; } + /** + * Set whether to cover or fill the specified dimensions + * + * @param string $mode + * + * @return \OC\Preview + */ + public function setMode($mode) { + $this->mode = $mode; + + return $this; + } + /** * Sets whether we need to generate a preview which keeps the aspect ratio of the original file * @@ -531,14 +548,22 @@ class Preview { * @param int $askedWidth * @param int $askedHeight * + * @param int $originalWidth + * @param int $originalHeight * @return \int[] */ - private function applyAspectRatio($askedWidth, $askedHeight) { - $originalRatio = $this->maxPreviewWidth / $this->maxPreviewHeight; + private function applyAspectRatio($askedWidth, $askedHeight, $originalWidth = 0, $originalHeight = 0) { + if(!$originalWidth){ + $originalWidth= $this->maxPreviewWidth; + } + if (!$originalHeight) { + $originalHeight = $this->maxPreviewHeight; + } + $originalRatio = $originalWidth / $originalHeight; // Defines the box in which the preview has to fit $scaleFactor = $this->scalingUp ? $this->maxScaleFactor : 1; - $askedWidth = min($askedWidth, $this->maxPreviewWidth * $scaleFactor); - $askedHeight = min($askedHeight, $this->maxPreviewHeight * $scaleFactor); + $askedWidth = min($askedWidth, $originalWidth * $scaleFactor); + $askedHeight = min($askedHeight, $originalHeight * $scaleFactor); if ($askedWidth / $originalRatio < $askedHeight) { // width restricted @@ -550,6 +575,32 @@ class Preview { return [(int)$askedWidth, (int)$askedHeight]; } + /** + * Resizes the boundaries to cover the area + * + * @param int $askedWidth + * @param int $askedHeight + * @param int $previewWidth + * @param int $previewHeight + * @return \int[] + */ + private function applyCover($askedWidth, $askedHeight, $previewWidth, $previewHeight) { + $originalRatio = $previewWidth / $previewHeight; + // Defines the box in which the preview has to fit + $scaleFactor = $this->scalingUp ? $this->maxScaleFactor : 1; + $askedWidth = min($askedWidth, $previewWidth * $scaleFactor); + $askedHeight = min($askedHeight, $previewHeight * $scaleFactor); + + if ($askedWidth / $originalRatio > $askedHeight) { + // height restricted + $askedHeight = round($askedWidth / $originalRatio); + } else { + $askedWidth = round($askedHeight * $originalRatio); + } + + return [(int)$askedWidth, (int)$askedHeight]; + } + /** * Makes sure an upscaled preview doesn't end up larger than the max dimensions defined in the * config @@ -791,7 +842,15 @@ class Preview { */ if ($this->keepAspect) { list($askedWidth, $askedHeight) = - $this->applyAspectRatio($askedWidth, $askedHeight); + $this->applyAspectRatio($askedWidth, $askedHeight, $previewWidth, $previewHeight); + } + + if ($this->mode === self::MODE_COVER) { + list($scaleWidth, $scaleHeight) = + $this->applyCover($askedWidth, $askedHeight, $previewWidth, $previewHeight); + } else { + $scaleWidth = $askedWidth; + $scaleHeight = $askedHeight; } /** @@ -799,7 +858,7 @@ class Preview { * Takes the scaling ratio into consideration */ list($newPreviewWidth, $newPreviewHeight) = $this->scale( - $image, $askedWidth, $askedHeight, $previewWidth, $previewHeight + $image, $scaleWidth, $scaleHeight, $previewWidth, $previewHeight ); // The preview has been resized and should now have the asked dimensions @@ -1000,6 +1059,9 @@ class Preview { if ($this->keepAspect && !$isMaxPreview) { $previewPath .= '-with-aspect'; } + if ($this->mode === self::MODE_COVER) { + $previewPath .= '-cover'; + } $previewPath .= '.png'; return $previewPath;