Skip to content
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

Merged
merged 2 commits into from
Jun 8, 2015
Merged

Fix max preview, some resizing and caching issues and force preview providers to resize their previews properly #16382

merged 2 commits into from
Jun 8, 2015

Conversation

oparoz
Copy link
Contributor

@oparoz oparoz commented May 16, 2015

TL;DR

This PR:

  • 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

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 ImageMagick
  • testimage.jpg | normal jpg with some text in it
  • testimage-wide.png | panoramic picture
  • testimageblah.gif | small animated gif

They 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

  • Pictures should never be bigger than 756x756 (using the config described above)
  • Whenever a picture is smaller than what is asked, it will be sent as is if the aspect ratio is required and with a transparent background if no aspect ratio is required.

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.

@oparoz oparoz self-assigned this May 16, 2015
@oparoz oparoz added this to the 8.1-current milestone May 16, 2015
@oparoz
Copy link
Contributor Author

oparoz commented May 16, 2015

Seems like the CI environment doesn't support movie, office and SVG conversion and my detection routine has failed, so I will update it.

@oparoz
Copy link
Contributor Author

oparoz commented May 16, 2015

@libasys - Since you've reported the problem, please test this.
Other interested parties: @georgehrke @DeepDiver1975 @MorrisJobke

@oparoz
Copy link
Contributor Author

oparoz commented May 16, 2015

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.

@libasys
Copy link
Contributor

libasys commented May 18, 2015

looks good!

* @param integer $maxHeight
* @return bool
*/
public function fitInIfTooBig($maxWidth, $maxHeight) {
Copy link
Contributor

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.

Copy link
Contributor Author

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.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

scaleToFit() ?
scaleDownToFit() ?

Copy link
Contributor

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) {
Copy link
Contributor

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)

Copy link
Contributor Author

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.

@oparoz
Copy link
Contributor Author

oparoz commented May 28, 2015

I'm going to push updated tests and the fixed Preview class which goes with it. It fixes a lot of reported issues with previews...

PHPUnit 4.5.0 by Sebastian Bergmann and contributors.

................................................................. 65 / 84 ( 77%)
...................

Time: 40.56 seconds, Memory: 34.50Mb

OK (84 tests, 567 assertions)

@oparoz
Copy link
Contributor Author

oparoz commented May 29, 2015

Nice, so if I've done my job right, this shows that the current Preview class fails 51 out of 164 tests.
I'll try to upload my fixed Preview class tomorrow.

https://ci.owncloud.org/job/pull-request-analyser-ng-simple/label=SLAVE/12578/console

@oparoz oparoz changed the title Make sure preview providers resize their previews properly Fix max preview, some resizing and caching issues and force preview providers to resize their previews properly May 29, 2015
@ghost
Copy link

ghost commented May 30, 2015

Refer to this link for build results (access rights to CI server needed):
https://ci.owncloud.org//job/pull-request-analyser-ng-simple/12598/
🚀 Test PASSed.🚀
chuck

@oparoz
Copy link
Contributor Author

oparoz commented May 30, 2015

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
@georgehrke @jancborchardt @jospoortvliet @libasys @davivel @setnes @PVince81 @DeepDiver1975 @MorrisJobke @RealRancor @rullzer

EDIT: Testing methodologies moved to OP


//save parameters
$this->setFile($file);
$this->setMaxX($maxX);
$this->setMaxY($maxY);
$this->setMaxX((int)$maxX);
Copy link
Contributor Author

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

Copy link
Member

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
Copy link
Member

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.

Copy link
Contributor Author

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**
@oparoz
Copy link
Contributor Author

oparoz commented Jun 6, 2015

Thanks for the review @LukasReschke 🍻
I've squashed + rebased and will add another commit once I understand your preference for $this in PHPDocs and what you need in terms of type hinting for arrays which are already typed.

@ghost
Copy link

ghost commented Jun 6, 2015

Refer to this link for build results (access rights to CI server needed):
https://ci.owncloud.org//job/pull-request-analyser-ng-simple/12720/
🚀 Test PASSed.🚀
chuck

@MorrisJobke
Copy link
Contributor

@LukasReschke Is this now okay from your side?

* @return bool
*/
public function scaleDownToFit($maxWidth, $maxHeight) {
$widthOrig = imageSX($this->resource);
Copy link
Member

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;
        }

Copy link
Contributor Author

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.

Copy link
Contributor Author

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.

Copy link
Member

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

@scrutinizer-notifier
Copy link

A new inspection was created.

@ghost
Copy link

ghost commented Jun 8, 2015

🚀 Test PASSed.🚀
chuck

@DeepDiver1975
Copy link
Member

👍 from my side - THX a lot!

DeepDiver1975 added a commit that referenced this pull request Jun 8, 2015
…he-size-of-their-preview

Fix max preview, some resizing and caching issues and force preview providers to resize their previews properly
@DeepDiver1975 DeepDiver1975 merged commit 64c9c27 into owncloud:master Jun 8, 2015
@jospoortvliet
Copy link

Yes, super awesome @oparoz thanks a bunch!

@lock lock bot locked as resolved and limited conversation to collaborators Aug 11, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants