-
-
Notifications
You must be signed in to change notification settings - Fork 4.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Modernize previews #37564
Modernize previews #37564
Conversation
Signed-off-by: Anderson Entwistle <[email protected]>
Fix preview providers generate thumbnails based on source file type instead of their type. This worked because providers were always called with a file of the same type. This is not an assumption that can be made any longer. Note that preview providers don't actually know their type - although they should - so instead make them respect an optional MIME type parameter to avoid potential breaking changes. Signed-off-by: Anderson Entwistle <[email protected]>
Signed-off-by: Anderson Entwistle <[email protected]>
Allow preview format to be specified to be a specific type for all files. Previously, preview format was the same type as the original file. Format can be jpeg, png, gif, webp, or avif. Signed-off-by: Anderson Entwistle <[email protected]>
Signed-off-by: Anderson Entwistle <[email protected]>
Signed-off-by: Anderson Entwistle <[email protected]>
$this->logger->error( | ||
'Preview quality must be an integer from 0 to 100; got ' . | ||
"$quality. Falling back to the default preview quality." | ||
); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Need to set the quality to the default here
$res = imagewebp($this->resource, null, $quality); | ||
break; | ||
case "image/avif": | ||
$res = imageavif($this->resource, null, $quality); |
Check failure
Code scanning / Psalm
UndefinedFunction
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing speed:
imageavif($this->resource, null, $quality,10);
@@ -727,6 +765,15 @@ | |||
$this->logger->debug('OC_Image->loadFromFile, webp images not supported: ' . $imagePath, ['app' => 'core']); | |||
} | |||
break; | |||
case IMAGETYPE_AVIF: |
Check failure
Code scanning / Psalm
UndefinedConstant
@@ -727,6 +765,15 @@ | |||
$this->logger->debug('OC_Image->loadFromFile, webp images not supported: ' . $imagePath, ['app' => 'core']); | |||
} | |||
break; | |||
case IMAGETYPE_AVIF: | |||
if (imagetypes() & IMG_AVIF) { |
Check failure
Code scanning / Psalm
UndefinedConstant
if (imagetypes() & IMG_AVIF) { | ||
if (!$this->checkImageSize($imagePath)) return false; | ||
|
||
$this->resource = imagecreatefromavif($imagePath); |
Check failure
Code scanning / Psalm
UndefinedFunction
@@ -108,10 +108,11 @@ | |||
* Check if a preview can be generated for a file | |||
* | |||
* @param \OCP\Files\FileInfo $file | |||
* @param ?string $previewMimeType MIME type of the preview to be generated |
Check failure
Code scanning / Psalm
MismatchingDocblockParamType
} | ||
|
||
public function isAvailable(FileInfo $file): bool { | ||
return (bool) (imagetypes() & IMG_AVIF); |
Check failure
Code scanning / Psalm
UndefinedConstant
if ($provider instanceof Imaginary) { | ||
return $provider->getCroppedThumbnail($file, $maxWidth, $maxHeight, $crop) ?? false; | ||
} | ||
return $provider->getThumbnail($file, $maxWidth, $maxHeight) ?? false; | ||
return $provider->getThumbnail($file, $maxWidth, $maxHeight, $mimeType) ?? false; |
Check failure
Code scanning / Psalm
TooManyArguments
I tried to avoid breaking changes because I was hoping to get this out quick as a feature release. Now I see that Nextcloud does not follow semantic versioning? Also the release cadence for majors is much quicker than expected... about every 6 months? If the target is next major then some stuff should be broken here. At minimum the default JPEG quality, which is currently preserved. |
/** | ||
* Default quality for jpeg images | ||
* | ||
* @deprecated this choice should be left to the image library | ||
* @see https://www.php.net/manual/en/function.imagejpeg.php#refsect1-function.imagejpeg-parameters | ||
*/ | ||
protected const DEFAULT_JPEG_QUALITY = 80; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
remove
@@ -381,12 +389,14 @@ public function data(): ?string { | |||
case "image/jpeg": | |||
/** @psalm-suppress InvalidScalarArgument */ | |||
imageinterlace($this->resource, (PHP_VERSION_ID >= 80000 ? true : 1)); | |||
$quality = $this->getJpegQuality(); | |||
$res = imagejpeg($this->resource, null, $quality); | |||
$res = imagejpeg($this->resource, null, $this->getJpegQuality()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
use $quality
(backed by format quality
setting from 0-100 with default -1 instead of format jpeg_quality
from 10-100 with default 80)
-1 -> ~75 (breaking change)
@@ -407,6 +444,8 @@ public function __toString() { | |||
|
|||
/** | |||
* @return int | |||
* | |||
* @deprecated | |||
*/ | |||
protected function getJpegQuality(): int { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
remove
@@ -51,6 +51,8 @@ class Generator { | |||
public const SEMAPHORE_ID_ALL = 0x0a11; | |||
public const SEMAPHORE_ID_NEW = 0x07ea; | |||
|
|||
private \OCP\ILogger $logger; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't actually write PHP. Can this leading slash be removed?
@@ -72,12 +82,49 @@ public function __construct( | |||
EventDispatcherInterface $legacyEventDispatcher, | |||
IEventDispatcher $eventDispatcher | |||
) { | |||
$this->logger = \OC::$server->getLogger(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can this leading slash be removed?
// Although we know the provider here, and it *should* know | ||
// its own MIME type, note that it actually doesn't - so we | ||
// have to pass it. | ||
// | ||
// *`IProviderV2->getMimeType`* | ||
// | ||
// > Regex with the mimetypes that are supported by this | ||
// provider | ||
// | ||
// This is also the case for `$this->getSmallImagePreview`. | ||
$preview = $this->helper->getThumbnail($provider, $file, $maxWidth, $maxHeight, false, $mimeType); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
High value target for another, potentially big breaking change. Should be a separate issue.. probably. I've already done too much refactoring here.
* | ||
* @deprecated this is goofy | ||
* @see https://www.php.net/manual/en/function.image-type-to-extension.php | ||
*/ | ||
private function getExtention($mimeType) { | ||
switch ($mimeType) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also consider targeting this... separate issue
// If quality is not set by the user or is invalid, then set it to the | ||
// GD default value to entrust choosing a well-optimized default | ||
// quality to the image library (which should make a much more educated | ||
// choice than we would make). Hopefully GD doesn't mangle this idea... | ||
// but it appears they do - WebP default should be 75 yet is 80. | ||
// | ||
// See https://developers.google.com/speed/webp/docs/cwebp#options | ||
if (!$quality) $quality = -1; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will be very hard to communicate effectively to users. We don't know what the defaults are, and defaults (when using -1) should be tuned to / vary by format. Maybe we should set a default? Also I have very little faith in PHP to handle this idea correctly even though it should..
@aentwist are you still working on this? Because to be mergeable the PR needs the be rebased (resolve conflicts) and the code analysis errors need to be fixed. Thank you :) |
No, I am not |
Sad, but thank you for the pull request! We can have this as inspiration to fix the issues. With PHP 8.1 providing AVIF support we should be able to mainline this with Nextcloud 30. |
Closing due to Nextcloud's jank release process, where I am unfortunately tagged for every single release, hopefully only under the condition that this is open. This is spot on with the rest of my Nextcloud experience. I do not, and have not ever used Nextcloud, cannot recommend Nextcloud, and do not like getting 5 emails from being tagged in a random beta release. Please feel free to use this, or even reopen it, when there is a plan to actually move it forward. Good luck. AVIF is awesome. |
Reopening in good faith in light of a newer alternative I have [to closing the PR] to not be tagged all the time #46946 (comment). Thank goodness, I really hope this can be useful.
|
In case someone asks why this was closed: Pull requests that get reassigned multiple major versions, thus not getting merged, are probably orphaned. |
And adding an extra reply, after reading this. I really appreciate you taking the time to write this, especially since you mentioned you're not a php dev, that shows some good faith. If someone wants to re-open or create a separate PR to continue this work, please feel free to do so. Unless this gets scheduled from other Nextcloud devs, if a PR isn't all green and ready, it's hard for us to invest that much time into guiding you to a mergeable state. We're always open for discussion, and the closure is not a definitive state, it's about cleaning staled PRs. |
Closes #13552
Closes #30118
Summary
See commits and #13552
TODO
Checklist