From b934b50867f51b7186119b22575d15fa45cdc7dc Mon Sep 17 00:00:00 2001 From: Andrew Murray Date: Fri, 28 Feb 2020 22:33:02 +1100 Subject: [PATCH 1/2] If an alpha channel is present, only use that to get bounding box --- Tests/test_image_getbbox.py | 37 ++++++++++++++++++++----------------- src/libImaging/GetBBox.c | 13 ++++++++++++- 2 files changed, 32 insertions(+), 18 deletions(-) diff --git a/Tests/test_image_getbbox.py b/Tests/test_image_getbbox.py index a80a1ca9d8e..c86e33eb2fb 100644 --- a/Tests/test_image_getbbox.py +++ b/Tests/test_image_getbbox.py @@ -10,29 +10,32 @@ def test_sanity(): def test_bbox(): + def check(im, fill_color): + assert im.getbbox() is None - # 8-bit mode - im = Image.new("L", (100, 100), 0) - assert im.getbbox() is None + im.paste(fill_color, (10, 25, 90, 75)) + assert im.getbbox() == (10, 25, 90, 75) - im.paste(255, (10, 25, 90, 75)) - assert im.getbbox() == (10, 25, 90, 75) + im.paste(fill_color, (25, 10, 75, 90)) + assert im.getbbox() == (10, 10, 90, 90) - im.paste(255, (25, 10, 75, 90)) - assert im.getbbox() == (10, 10, 90, 90) + im.paste(fill_color, (-10, -10, 110, 110)) + assert im.getbbox() == (0, 0, 100, 100) - im.paste(255, (-10, -10, 110, 110)) - assert im.getbbox() == (0, 0, 100, 100) + # 8-bit mode + im = Image.new("L", (100, 100), 0) + check(im, 255) # 32-bit mode im = Image.new("RGB", (100, 100), 0) - assert im.getbbox() is None - - im.paste(255, (10, 25, 90, 75)) - assert im.getbbox() == (10, 25, 90, 75) + check(im, 255) - im.paste(255, (25, 10, 75, 90)) - assert im.getbbox() == (10, 10, 90, 90) + for mode in ("RGBA", "RGBa"): + for color in ((0, 0, 0, 0), (127, 127, 127, 0), (255, 255, 255, 0)): + im = Image.new(mode, (100, 100), color) + check(im, (255, 255, 255, 255)) - im.paste(255, (-10, -10, 110, 110)) - assert im.getbbox() == (0, 0, 100, 100) + for mode in ("La", "LA", "PA"): + for color in ((0, 0), (127, 0), (255, 0)): + im = Image.new(mode, (100, 100), color) + check(im, (255, 255)) diff --git a/src/libImaging/GetBBox.c b/src/libImaging/GetBBox.c index b63888f8746..bf5d61dd32d 100644 --- a/src/libImaging/GetBBox.c +++ b/src/libImaging/GetBBox.c @@ -55,8 +55,19 @@ ImagingGetBBox(Imaging im, int bbox[4]) GETBBOX(image8, 0xff); } else { INT32 mask = 0xffffffff; - if (im->bands == 3) + if (im->bands == 3) { ((UINT8*) &mask)[3] = 0; + } else if (strcmp(im->mode, "RGBa") == 0 || + strcmp(im->mode, "RGBA") == 0 || + strcmp(im->mode, "La") == 0 || + strcmp(im->mode, "LA") == 0 || + strcmp(im->mode, "PA") == 0) { +#ifdef WORDS_BIGENDIAN + mask = 0x000000ff; +#else + mask = 0xff000000; +#endif + } GETBBOX(image32, mask); } From b888354ce92ea93a230d0105b8be4e20d00ad53a Mon Sep 17 00:00:00 2001 From: Andrew Murray Date: Thu, 5 Mar 2020 21:25:39 +1100 Subject: [PATCH 2/2] Document getbbox change for images with alpha [ci skip] --- docs/releasenotes/7.1.0.rst | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/docs/releasenotes/7.1.0.rst b/docs/releasenotes/7.1.0.rst index f9639a636be..6310023f4f5 100644 --- a/docs/releasenotes/7.1.0.rst +++ b/docs/releasenotes/7.1.0.rst @@ -1,6 +1,9 @@ 7.0.0 ----- +API Changes +=========== + Allow saving of zero quality JPEG images ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -14,3 +17,15 @@ been resolved. from PIL import Image im = Image.open("hopper.jpg") im.save("out.jpg", quality=0) + +Other Changes +============= + +If present, only use alpha channel for bounding box +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +When the :py:meth:`~PIL.Image.Image.getbbox` method calculates the bounding +box, for an RGB image it trims black pixels. Similarly, for an RGBA image it +would trim black transparent pixels. This is now changed so that if an image +has an alpha channel (RGBA, RGBa, PA, LA, La), any transparent pixels are +trimmed.