-
Notifications
You must be signed in to change notification settings - Fork 2.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
Fix max preview, some resizing and caching issues and force preview providers to resize their previews properly #16382
Fix max preview, some resizing and caching issues and force preview providers to resize their previews properly #16382
Conversation
Seems like the CI environment doesn't support movie, office and SVG conversion and my detection routine has failed, so I will update it. |
@libasys - Since you've reported the problem, please test this. |
Also, I've introduced some test documents, feel free to give me replacements if you have better ones. I tried to use oC material, but couldn't find a short MP3 and MP4. |
looks good! |
* @param integer $maxHeight | ||
* @return bool | ||
*/ | ||
public function fitInIfTooBig($maxWidth, $maxHeight) { |
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 from public interface?
Also I don't think the name is very suitable.
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.
Yes, I missed it.
OK about the name.
Let's first validate the concept, then I'll accept any name. I find the original fitIn
ambiguous because it actually stretches the image to fill the space, so we need a descriptive method name.
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.
scaleToFit() ?
scaleDownToFit() ?
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.
scaleToFit() sounds good. If a small image is stretched to fill the space, this info should be added to the PHPDoc as well.
$widthOrig = imageSX($this->resource); | ||
$heightOrig = imageSY($this->resource); | ||
|
||
if ($widthOrig > $maxWidth || $heightOrig >$maxHeight) { |
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.
Should this be >=
(just asking, I'm not sure myself)
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 think so. If it fits in the box already, we don't need to process it further.
I'm going to push updated tests and the fixed
|
Nice, so if I've done my job right, this shows that the current Preview class fails 51 out of 164 tests. https://ci.owncloud.org/job/pull-request-analyser-ng-simple/label=SLAVE/12578/console |
Refer to this link for build results (access rights to CI server needed): |
OK, so 164 tests were passed and 1127 assertions were verified for the Preview class alone I've also performed extensive real world testing and now it's time for you to do the same EDIT: Testing methodologies moved to OP |
|
||
//save parameters | ||
$this->setFile($file); | ||
$this->setMaxX($maxX); | ||
$this->setMaxY($maxY); | ||
$this->setMaxX((int)$maxX); |
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.
The idea is to make sure we get valid dimensions
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.
🚀
* @throws \Exception | ||
* @return mixed (bool / string) | ||
* false if thumbnail does not exist | ||
* path to thumbnail if thumbnail exists | ||
*/ | ||
public function __construct($user = '', $root = '/', $file = '', $maxX = 1, $maxY = 1, $scalingUp = true) { | ||
public function __construct( | ||
$user = '', $root = '/', $file = '', $maxX = 1, $maxY = 1, $scalingUp = true |
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.
While squashing please move each to it's own line - THX.
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.
✓
…roviders to resize their previews properly * introduces a method in OC_Image which doesn't stretch images when trying to make them fit in a box * adds the method to all key providers so that they can do their job, as expected by the Preview class * improves the caching mechanism of Preview in order to reduce I/O and to avoid filling the available disk space * fixes some long standing issues * **contains mostly tests**
Thanks for the review @LukasReschke 🍻 |
Refer to this link for build results (access rights to CI server needed): |
@LukasReschke Is this now okay from your side? |
* @return bool | ||
*/ | ||
public function scaleDownToFit($maxWidth, $maxHeight) { | ||
$widthOrig = imageSX($this->resource); |
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.
test if $this->resource is valid is missing here - use
if (!$this->valid()) {
$this->logger->error(__METHOD__ . '(): No image loaded', array('app' => 'core'));
return false;
}
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 removed this on purpose since we either return false or call fitIn
which will make sure there is an image to work on before trying to process it, but I can see now why it's still a good idea to have it since the method is first determining the size of the resource in order to make a decision.
I think in a future version of oC, we could even merge the two methods by adding an extra argument. I didn't want to touch the original this late in the game.
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.
Or should I modify the original method in this PR to avoid duplication?
public function fitIn($maxWidth, $maxHeight, $scalingUp = false)
The method is tested and only doing something very specific, so it should be a low risk. Also, the method has not been public until now.
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 think in a future version of oC, we could even merge the two methods by adding an extra argument. I didn't want to touch the original this late in the game.
I'd walk this path for now - THX
A new inspection was created. |
👍 from my side - THX a lot! |
…he-size-of-their-preview Fix max preview, some resizing and caching issues and force preview providers to resize their previews properly
Yes, super awesome @oparoz thanks a bunch! |
TL;DR
This PR:
Description
#13607 describes what needed to be done at the provider level in order to support the max preview feature, but unfortunately, only the bitmap provider was fixed until now and this led to some max previews being cropped (#16355).
Since all the other providers end up with an \OC_Image object, they can simply use one of the available methods to make sure the preview they create fits in the asked dimension. I decided to call that method from within each provider since they're responsible to provide a preview which matches the requirements.
Unfortunately, since none of the available method does the job, a new one had to be introduced to make sure a smaller preview wouldn't be stretched to fit in the max dimensions.
One test per group of provider is provided.
Also, since when working on this I encountered many bugs, both introduced by the max preview and through the years, I've decided to write tests (41 x 4 samples) for the Preview class to try and detect most of the problems and to fix them.
This branch will now also fix
Enjoy and hopefully this will be working well for all of you!
I'm also open to discussing testing strategies as this is not easy to do properly and requires large data samples.
Test data
I suggest you upload at least these 4 pictures from the tests/data folder to your test folder:
testimage.eps
| standard eps file, converted by ImageMagicktestimage.jpg
| normal jpg with some text in ittestimage-wide.png
| panoramic picturetestimageblah.gif
| small animated gifThey were chosen because they trigger different scenarios in the resizing mechanism. You're welcome to test with your libraries as well, just make sure you've deleted the thumbnail folder before proceeding.
Your configuration should have the max preview dimensions set at 756x756 if you want to be able to really test the various restrictions the resizing can encouter.
If you want to test upscaling, then you should have a max_factor of above 1.0 in your configuration
Tests
URLs
No aspect ratio
/index.php/core/preview.png?file=testimage.jpg&x=756&y=756&forceIcon=1
With ratio
/index.php/core/preview.png?file=testimage.jpg&x=756&y=756&forceIcon=1&a
You're encouraged to play with various sizes, to see the effect it has on the rendering
It's also possible to disable upscaling by adding this to the URL:
&scalingup=0
, but you will need to delete your thumbnails folder in order to be able to get real results, since there is no mechanism in place which detects if a preview has been upscaled or not. We currently only track with or without aspect ratio.Gallery
I also invite you to install Gallery 8.1 to test this since it will generate thumbnails and large previews and would be a good quick test.
Make sure you increase the the max preview dimensions and delete the thumbnails folder prior to testing or your large previews will look tiny.
Mobile clients
You should be getting the same previews you were getting before, except maybe a few "fixed" ones.
Test results
I've left lots of debugging messages (to be cleanup later), so by looking at the logs, you should be getting an idea of what the class is trying to do with the request it's been given.