mirror of
https://github.com/python-pillow/Pillow.git
synced 2024-12-26 18:06:18 +03:00
Merge pull request #2707 from uploadcare/fix-box-resize
Fix resize with box when no resize required
This commit is contained in:
commit
e6456643d4
|
@ -344,6 +344,7 @@ class CoreResamplePassesTest(PillowTestCase):
|
|||
cropped = im.crop(box).resize(im.size, Image.BILINEAR)
|
||||
self.assert_image_similar(with_box, cropped, 0.1)
|
||||
|
||||
|
||||
class CoreResampleCoefficientsTest(PillowTestCase):
|
||||
def test_reduce(self):
|
||||
test_color = 254
|
||||
|
@ -458,6 +459,86 @@ class CoreResampleBoxTest(PillowTestCase):
|
|||
cropped = im.crop(box).resize((32, 32), resample)
|
||||
self.assert_image_similar(cropped, with_box, 0.4)
|
||||
|
||||
def test_passthrough(self):
|
||||
"When no resize is required"
|
||||
im = hopper()
|
||||
|
||||
for size, box in [
|
||||
((40, 50), (0, 0, 40, 50)),
|
||||
((40, 50), (0, 10, 40, 60)),
|
||||
((40, 50), (10, 0, 50, 50)),
|
||||
((40, 50), (10, 20, 50, 70)),
|
||||
]:
|
||||
try:
|
||||
res = im.resize(size, Image.LANCZOS, box)
|
||||
self.assertEqual(res.size, size)
|
||||
self.assert_image_equal(res, im.crop(box))
|
||||
except AssertionError:
|
||||
print('>>>', size, box)
|
||||
raise
|
||||
|
||||
def test_no_passthrough(self):
|
||||
"When resize is required"
|
||||
im = hopper()
|
||||
|
||||
for size, box in [
|
||||
((40, 50), (0.4, 0.4, 40.4, 50.4)),
|
||||
((40, 50), (0.4, 10.4, 40.4, 60.4)),
|
||||
((40, 50), (10.4, 0.4, 50.4, 50.4)),
|
||||
((40, 50), (10.4, 20.4, 50.4, 70.4)),
|
||||
]:
|
||||
try:
|
||||
res = im.resize(size, Image.LANCZOS, box)
|
||||
self.assertEqual(res.size, size)
|
||||
with self.assertRaisesRegexp(AssertionError, "difference \d"):
|
||||
# check that the difference at least that much
|
||||
self.assert_image_similar(res, im.crop(box), 20)
|
||||
except AssertionError:
|
||||
print('>>>', size, box)
|
||||
raise
|
||||
|
||||
def test_skip_horizontal(self):
|
||||
"Can skip resize in one dimension"
|
||||
im = hopper()
|
||||
|
||||
for flt in [Image.NEAREST, Image.BICUBIC]:
|
||||
for size, box in [
|
||||
((40, 50), (0, 0, 40, 90)),
|
||||
((40, 50), (0, 20, 40, 90)),
|
||||
((40, 50), (10, 0, 50, 90)),
|
||||
((40, 50), (10, 20, 50, 90)),
|
||||
]:
|
||||
try:
|
||||
res = im.resize(size, flt, box)
|
||||
self.assertEqual(res.size, size)
|
||||
# Borders should be slightly different
|
||||
self.assert_image_similar(
|
||||
res, im.crop(box).resize(size, flt), 0.4)
|
||||
except AssertionError:
|
||||
print('>>>', size, box, flt)
|
||||
raise
|
||||
|
||||
def test_skip_vertical(self):
|
||||
"Can skip resize in one dimension"
|
||||
im = hopper()
|
||||
|
||||
for flt in [Image.NEAREST, Image.BICUBIC]:
|
||||
for size, box in [
|
||||
((40, 50), (0, 0, 90, 50)),
|
||||
((40, 50), (20, 0, 90, 50)),
|
||||
((40, 50), (0, 10, 90, 60)),
|
||||
((40, 50), (20, 10, 90, 60)),
|
||||
]:
|
||||
try:
|
||||
res = im.resize(size, flt, box)
|
||||
self.assertEqual(res.size, size)
|
||||
# Borders should be slightly different
|
||||
self.assert_image_similar(
|
||||
res, im.crop(box).resize(size, flt), 0.4)
|
||||
except AssertionError:
|
||||
print('>>>', size, box, flt)
|
||||
raise
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
|
|
@ -1529,8 +1529,10 @@ _resize(ImagingObject* self, PyObject* args)
|
|||
return ImagingError_ValueError("box can't be empty");
|
||||
}
|
||||
|
||||
if (box[0] == 0 && box[1] == 0 && box[2] == xsize && box[3] == ysize) {
|
||||
imOut = ImagingCopy(imIn);
|
||||
// If box's coordinates are int and box size matches requested size
|
||||
if (box[0] - (int) box[0] == 0 && box[2] - box[0] == xsize
|
||||
&& box[1] - (int) box[1] == 0 && box[3] - box[1] == ysize) {
|
||||
imOut = ImagingCrop(imIn, box[0], box[1], box[2], box[3]);
|
||||
}
|
||||
else if (filter == IMAGING_TRANSFORM_NEAREST) {
|
||||
double a[6];
|
||||
|
|
|
@ -553,12 +553,15 @@ ImagingResampleInner(Imaging imIn, int xsize, int ysize,
|
|||
Imaging imTemp = NULL;
|
||||
Imaging imOut = NULL;
|
||||
|
||||
int i;
|
||||
int yroi_min, yroi_max;
|
||||
int i, need_horizontal, need_vertical;
|
||||
int ybox_first, ybox_last;
|
||||
int ksize_horiz, ksize_vert;
|
||||
int *bounds_horiz, *bounds_vert;
|
||||
double *kk_horiz, *kk_vert;
|
||||
|
||||
need_horizontal = xsize != imIn->xsize || box[0] || box[2] != xsize;
|
||||
need_vertical = ysize != imIn->ysize || box[1] || box[3] != ysize;
|
||||
|
||||
ksize_horiz = precompute_coeffs(imIn->xsize, box[0], box[2], xsize,
|
||||
filterp, &bounds_horiz, &kk_horiz);
|
||||
if ( ! ksize_horiz) {
|
||||
|
@ -574,21 +577,21 @@ ImagingResampleInner(Imaging imIn, int xsize, int ysize,
|
|||
}
|
||||
|
||||
// First used row in the source image
|
||||
yroi_min = bounds_vert[0];
|
||||
ybox_first = bounds_vert[0];
|
||||
// Last used row in the source image
|
||||
yroi_max = bounds_vert[ysize*2 - 2] + bounds_vert[ysize*2 - 1];
|
||||
ybox_last = bounds_vert[ysize*2 - 2] + bounds_vert[ysize*2 - 1];
|
||||
|
||||
|
||||
/* two-pass resize, first pass */
|
||||
if (box[0] || box[2] != xsize) {
|
||||
/* two-pass resize, horizontal pass */
|
||||
if (need_horizontal) {
|
||||
// Shift bounds for vertical pass
|
||||
for (i = 0; i < ysize; i++) {
|
||||
bounds_vert[i * 2] -= yroi_min;
|
||||
bounds_vert[i * 2] -= ybox_first;
|
||||
}
|
||||
|
||||
imTemp = ImagingNewDirty(imIn->mode, xsize, yroi_max - yroi_min);
|
||||
imTemp = ImagingNewDirty(imIn->mode, xsize, ybox_last - ybox_first);
|
||||
if (imTemp) {
|
||||
ResampleHorizontal(imTemp, imIn, yroi_min,
|
||||
ResampleHorizontal(imTemp, imIn, ybox_first,
|
||||
ksize_horiz, bounds_horiz, kk_horiz);
|
||||
}
|
||||
free(bounds_horiz);
|
||||
|
@ -605,8 +608,8 @@ ImagingResampleInner(Imaging imIn, int xsize, int ysize,
|
|||
free(kk_horiz);
|
||||
}
|
||||
|
||||
/* second pass */
|
||||
if (box[1] || box[3] != ysize) {
|
||||
/* vertical pass */
|
||||
if (need_vertical) {
|
||||
imOut = ImagingNewDirty(imIn->mode, imIn->xsize, ysize);
|
||||
if (imOut) {
|
||||
/* imIn can be the original image or horizontally resampled one */
|
||||
|
|
Loading…
Reference in New Issue
Block a user