-
-
Notifications
You must be signed in to change notification settings - Fork 2.4k
Reduce for resize #4273
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
Reduce for resize #4273
Conversation
src/PIL/Image.py
Outdated
| return m_im | ||
|
|
||
| def resize(self, size, resample=NEAREST, box=None): | ||
| def resize(self, size, resample=NEAREST, box=None, max_reduce=None): |
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.
Maybe the better name is reduce_gap since this is actually minimal distance (in terms of scale) between the reduce() method result size and the requested size.
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.
Renamed to reducing_gap
src/PIL/Image.py
Outdated
| if res is not None: | ||
| box = res[1] | ||
| if max_reduce is not None: | ||
| res = self.draft(None, (size[0] * max_reduce, size[1] * max_reduce)) |
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.
On the one hand, thumbnail() now takes max_reduce into account when working with JPEGs and achieves indistinguishable quality like when it works with any other images.
src/PIL/Image.py
Outdated
|
|
||
| if self.size != size: | ||
| im = self.resize(size, resample, box=box) | ||
| im = self.resize(size, resample, box=box, max_reduce=max_reduce) |
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.
On the other hand, thumbnail() takes max_reduce into account when working with any other images and achieves compared speed as when working with JPEGs.
Huge win!
# Conflicts: # docs/releasenotes/7.0.0.rst # src/PIL/Image.py
c02d48c to
fc28182
Compare
# Conflicts: # docs/releasenotes/7.0.0.rst
hugovk
left a comment
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.
A few minor suggestions.
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ||
|
|
||
| Speeds up resizing by resizing the image in two steps. The bigger ``reducing_gap``, | ||
| the closer the result to the fair resampling. The smaller ``reducing_gap``, |
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.
What is meant by "fair resampling"?
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 means resampling in one operation, as before, without .reduce() operation.
# Conflicts: # docs/releasenotes/7.0.0.rst
This PR is a logical conclusion of #4251 and #4231 (and also the old one #2254) and shouldn't be merged first. All the new code in the single commit: fa9e85c
With all these tools (
.reduce()method andboxargument for.resize()method) we finally have an extremely precise image resize approximation which works in times faster on a very large image reduce.Performance
With a very realistic value (reducing_gap=2.0) this method speed ups resizing in 4.2 times. This like Pillow-SIMD but without SIMD :-)
It performs even better with more heavy
LANCZOSfilter (5.3 times faster):Accuracy
try_reduce.py
Bicubic
Reference (

reducing_gap=None):reducing_gap=3.0and inverted difference (yes, there is the second image):reducing_gap=2.0and inverted difference (wipe your screen):reducing_gap=1.0and inverted difference:Lanczos
Reference (

reducing_gap=None):reducing_gap=3.0and inverted difference:reducing_gap=2.0and inverted difference:reducing_gap=1.0and inverted difference:So the difference between fair resampling and
reducing_gap=2.0is indistinguishable by eye.reducing_gapmore than 3.0 is simply meaningless.Bonus track: the inverted difference between

BICUBICandLANCZOS:TODO list
boxargument fromreduce()method to reduce image region