-
-
Notifications
You must be signed in to change notification settings - Fork 2.4k
Region of interest (box) for resampling #2254
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
Conversation
_imaging.c
Outdated
| {"resize", (PyCFunction)_resize, 1}, | ||
| // There were two methods for image resize before. | ||
| // Starting from Pillow 2.7.0 stretch is depreciated. | ||
| {"stretch", (PyCFunction)_resize, 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.
The deprecated internal method is removed
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.
Do you want to hoist that into its own PR?
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.
ok, I'll do
PIL/Image.py
Outdated
| return self.im.putpixel(xy, value) | ||
|
|
||
| def resize(self, size, resample=NEAREST): | ||
| def resize(self, size, resample=NEAREST, roi=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.
Another possible name is box=None like in Image.crop().
I would not refuse help with English docstring. My suggestion:
The region of interest for the source image. A (left, upper, right, lower)-tuple of floats. If not provided, the entire source image is used.
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 like box for a parameter name. This parameter runs the equivalent of resize(crop(box)), so matching the Image.crop name makes sense.
|
I've found performance regression in |
This reverts commit e7569a1.
kmax → ksize
|
I've updated PR info. I wasn't expected such massive changes, unfortunately. The main problem was that ImagingResampleHorizontal/Vertical functions used to calculate coefficients on its own. This led to code blowing, so I decided to move |
| ResampleHorizontal(imTemp, imIn, yroi_min, | ||
| ksize_horiz, bounds_horiz, kk_horiz); | ||
| } | ||
| free(bounds_horiz); |
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.
Memory leak if this step is not performed
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.
resolved
| if previous step was not performed. */ | ||
| ImagingDelete(imTemp); | ||
| if ( ! imOut) | ||
| free(bounds_vert); |
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.
Memory leak if this step is not performed
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.
resolved
pass box for RGBA → RGBa conversion
|
More bugs were fixed |
|
@homm Are you happy with this one? |
|
@wiredfool Now this looks good :-) |
# Conflicts: # libImaging/Resample.c
|
Rebased |
Implements source ROI for resampling. Explanation
In a loose sens,
im.resize(size, resample, box)is very similar toim.crop(box).resize(size, resample). But there are two differences:Box dimensions are not required to be integer. Now it is possible to create resized images with subpixel accuracy.
While
boxpoints out mathematical constraints, it doesn't limit actual pixels. Border lines and rows still depends on pixels outside of the box.This reveals several use cases:
Tile resampling
In opposite to crop + resize, tiles resized from the source image using box argument, will perfect match pixels from image resized without crop.
Original image
tiles.py
Multistep resampling
In some cases we can perform one very cheap (or even free) supersampling resampling (e.g. during JPEG decoding) and then resize to target dimensions. The problem is that JPEG supersampling works only with whole pixels (for example, scaling 8×8 pixel into one). That is why 256×256 and 249×249 images both will be scaled to 32x32 image. This introduces geometric distortion. But with subsampling scaling we can scale 31.125×31.125 image to target dimension without geometric distortion.
Operations reordering
This may be very similar to previous topic. If we have some crop and resize operations sequence, we used to have to perform it in defined order. Otherwise we would have cumulative rounding and geometric distortion errors. With subpixel resampling box, we can reorder operations on our need: for example, merge all operations in single resample with box.