Repository navigation
Conversation
BOX coefficient ranges used (int)(center ± support + 0.5) plus a discontinuous kernel, so a source pixel whose center landed on an output bin edge could get weight 0 in every output. Tile downscale bins as (left, right] so each source pixel maps to one destination. Co-authored-by: CenFangyu <Dmao233@users.noreply.github.com>
Avoid the deprecated Image.getdata API in the python-pillow#9939 test. Co-authored-by: CenFangyu <Dmao233@users.noreply.github.com>
Co-authored-by: CenFangyu <Dmao233@users.noreply.github.com>
Co-authored-by: CenFangyu <Dmao233@users.noreply.github.com>
|
I've created Dmao233#2 with a suggestion. |
Took radarhere's Simplify code suggestion.
|
Took the Simplify code suggestion from Dmao233#2. |
Keep the BOX downscale note and the HarfBuzz wheel note. Co-authored-by: CenFangyu <Dmao233@users.noreply.github.com>
|
Merged main; releasenotes conflict in 13.0.0.rst resolved (kept BOX note). e7be905. |
|
I checked e7be905 against 5835da6 in isolated native builds. This also fixes a duplication case that would be useful beside the dropped-pixel regressions: shrinking 15 pixels to 14 can count the central source pixel twice on the old implementation. from PIL import Image
im = Image.new("L", (15, 1))
im.putpixel((7, 0), 255)
out = im.resize((14, 1), Image.Resampling.BOX)
assert [value for value in out.get_flattened_data() if value] == [128]The base produces two nonzero values, [128, 128]; this head produces [128]. The vertical 1×15 → 1×14 case agrees. That assertion checks exactly one contribution without prescribing which side owns the boundary tie. On this head, all 59 selftests passed and the focused resampling suite had 103 passes and 2 expected failures. I also verified the small example above on both native builds. I haven’t run the full suite. |
|
Thanks, added it as a test for both directions in f1670bf; fails on main, passes here. |
|
What do you think of #10165? It passes all of the tests from this PR, and certainly looks simpler. |
|
Checked #10165 against the tests here (boundary drop + 15→14 double-count, both axes): all pass. Prefer this PR on the approach: BOX downscale should tile If you still prefer #10165 for the smaller diff, I can close this. |
| :data:`PIL.Image.Resampling.BOX` downscaling could skip a source pixel whose | ||
| center landed on an output bin edge, due to range rounding and the discontinuous | ||
| box kernel. Those pixels are now assigned to exactly one output pixel, matching | ||
| the documented "each source pixel contributes to one destination pixel" behavior. |
There was a problem hiding this comment.
| :data:`PIL.Image.Resampling.BOX` downscaling could skip a source pixel whose | |
| center landed on an output bin edge, due to range rounding and the discontinuous | |
| box kernel. Those pixels are now assigned to exactly one output pixel, matching | |
| the documented "each source pixel contributes to one destination pixel" behavior. | |
| :data:`PIL.Image.Resampling.BOX` downscaling could skip a source pixel whose center | |
| landed on an output bin edge, due to range rounding and the discontinuous box kernel. | |
| Those pixels are now assigned to exactly one output pixel, matching the documented | |
| behavior that "Each pixel of the source image contributes to one pixel of the | |
| destination image with identical weights" |
I suspect you're quoting https://pillow.readthedocs.io/en/latest/handbook/concepts.html#filters. If so, let's make what's inside the quote marks exact.
| /* BOX maps each source pixel to exactly one output with equal weights. | ||
| When downscaling, (int)(center ± support + 0.5) and the discontinuous | ||
| box kernel can both miss a pixel whose center lands on a bin edge | ||
| (issue #9939). Tile bins as (left, right] instead. */ |
There was a problem hiding this comment.
| /* BOX maps each source pixel to exactly one output with equal weights. | |
| When downscaling, (int)(center ± support + 0.5) and the discontinuous | |
| box kernel can both miss a pixel whose center lands on a bin edge | |
| (issue #9939). Tile bins as (left, right] instead. */ | |
| /* For BOX, each source pixel contributes to one output pixel with equal weights. | |
| When downscaling, (int)(center ± support + 0.5) and the discontinuous box kernel | |
| can both miss a pixel whose center lands on a bin edge (issue #9939). | |
| Tile bins as (left, right] instead. */ |
Maybe it's just me, but 'maps each source pixel to exactly one output' sounds like a one-to-one mapping, which it isn't.
Per review feedback on python-pillow#9949.
|
Took both wording suggestions in 7720f83. |
Fixes #9939.
Changes proposed in this pull request:
docs/releasenotes/13.0.0.rst