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

Use minimal scale for jpeg drafts #2240

Merged
merged 2 commits into from Nov 22, 2016

Conversation

homm
Copy link
Member

@homm homm commented Nov 22, 2016

This fixes .draft() when requested aspect ratio doesn't match the original one.

from PIL import Image
im = Image.open('dice_illusion.jpg')
im.draft(None, (150, 45))
im = im.resize((150, 45), Image.BICUBIC)
im.save('_out.jpg', quality=90)

Source image
dice_illusion

Results before/after
_out _out fixed

@homm
Copy link
Member Author

homm commented Nov 22, 2016

Also added protection from second .draft() call. Otherwise:

$ time python ./Tests/test_image_draft.py
.E*** Error in `python': free(): invalid next size (fast): 0x000000000128c990 ***
Aborted (core dumped)

((128, 128), (16, 16), (16, 16)),

# large requested width
((435, 361), (218, 128), (435, 361)), # almost 2x
Copy link
Member

Choose a reason for hiding this comment

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

Does this mean that if we request a draft image of (218, 128), we're getting something larger than that?

@homm
Copy link
Member Author

homm commented Nov 22, 2016

Does this mean that if we request a draft image of (218, 128), we're getting something larger than that?

Yes. And this is absolutely correct. The main idea behind the draft method is: it shouldn't truncate more information than defined. There are some details that should clarify.

First of all, this fix doesn't change the behavior when aspect ratios are the same or near the same. The draft image will be the same size as requested or larger. Look at this, for example. We don't lose more information than define in the .draft() call.

Second, it can look weird but we can't return (218, 181) when requested size is (218, 181). This also matches the previous behavior but required further explanation. The original image size is (435, 361). When we downscale it in two times, the result image size should be (217.5, 180.5). Of course, we can't return fractional pixels. So the actually returned size will be (218, 181). But requested size (218, 181) is still greater than (217.5, 180.5), so we are returning the original image without downscaling to do not lose more information than defined.

Third, and the only what is really changed. When we can scale one dimension more than other, we don't scale as much as possible. Instead, we are trying do not lose more information than define :-)

@wiredfool wiredfool merged commit 620d082 into python-pillow:master Nov 22, 2016
@homm homm deleted the draft-min-scale branch November 22, 2016 15:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants