From 7d3274518d2e18559f164cd2335c7700249763d7 Mon Sep 17 00:00:00 2001 From: Andrew Murray Date: Tue, 1 Mar 2022 21:05:42 +1100 Subject: [PATCH] Allow LA to be used as a mask in paste() --- Tests/test_image_paste.py | 32 ++++++++++++++++++++++++++++++++ src/PIL/GifImagePlugin.py | 2 +- src/PIL/Image.py | 6 +++--- src/libImaging/Paste.c | 2 +- 4 files changed, 37 insertions(+), 5 deletions(-) diff --git a/Tests/test_image_paste.py b/Tests/test_image_paste.py index dc3caef01..281d5a6fb 100644 --- a/Tests/test_image_paste.py +++ b/Tests/test_image_paste.py @@ -67,6 +67,16 @@ class TestImagingPaste: ], ) + @cached_property + def gradient_LA(self): + return Image.merge( + "LA", + [ + self.gradient_L, + self.gradient_L.transpose(Image.Transpose.ROTATE_90), + ], + ) + @cached_property def gradient_RGBA(self): return Image.merge( @@ -145,6 +155,28 @@ class TestImagingPaste: ], ) + def test_image_mask_LA(self): + for mode in ("RGBA", "RGB", "L"): + im = Image.new(mode, (200, 200), "white") + im2 = getattr(self, "gradient_" + mode) + + self.assert_9points_paste( + im, + im2, + self.gradient_LA, + [ + (128, 191, 255, 191), + (112, 207, 206, 111), + (128, 254, 128, 1), + (208, 208, 239, 239), + (192, 191, 191, 191), + (207, 207, 112, 113), + (255, 255, 255, 255), + (239, 207, 207, 239), + (255, 191, 128, 191), + ], + ) + def test_image_mask_RGBA(self): for mode in ("RGBA", "RGB", "L"): im = Image.new(mode, (200, 200), "white") diff --git a/src/PIL/GifImagePlugin.py b/src/PIL/GifImagePlugin.py index b222235d8..12d85263b 100644 --- a/src/PIL/GifImagePlugin.py +++ b/src/PIL/GifImagePlugin.py @@ -385,7 +385,7 @@ class GifImageFile(ImageFile.ImageFile): self.im = self._prev_im self.mode = self.im.mode - if frame_im.mode == "RGBA": + if frame_im.mode in ("LA", "RGBA"): self.im.paste(frame_im, self.dispose_extent, frame_im) else: self.im.paste(frame_im, self.dispose_extent) diff --git a/src/PIL/Image.py b/src/PIL/Image.py index 352d77fe7..01bdb3612 100644 --- a/src/PIL/Image.py +++ b/src/PIL/Image.py @@ -1566,8 +1566,8 @@ class Image: also use color strings as supported by the ImageColor module. If a mask is given, this method updates only the regions - indicated by the mask. You can use either "1", "L" or "RGBA" - images (in the latter case, the alpha band is used as mask). + indicated by the mask. You can use either "1", "L", "LA", "RGBA" + or "RGBa" images (if present, the alpha band is used as mask). Where the mask is 255, the given image is copied as is. Where the mask is 0, the current value is preserved. Intermediate values will mix the two images together, including their alpha @@ -1615,7 +1615,7 @@ class Image: elif isImageType(im): im.load() if self.mode != im.mode: - if self.mode != "RGB" or im.mode not in ("RGBA", "RGBa"): + if self.mode != "RGB" or im.mode not in ("LA", "RGBA", "RGBa"): # should use an adapter for this! im = im.convert(self.mode) im = im.im diff --git a/src/libImaging/Paste.c b/src/libImaging/Paste.c index be26cd260..fafd8141e 100644 --- a/src/libImaging/Paste.c +++ b/src/libImaging/Paste.c @@ -295,7 +295,7 @@ ImagingPaste( paste_mask_L(imOut, imIn, imMask, dx0, dy0, sx0, sy0, xsize, ysize, pixelsize); ImagingSectionLeave(&cookie); - } else if (strcmp(imMask->mode, "RGBA") == 0) { + } else if (strcmp(imMask->mode, "LA") == 0 || strcmp(imMask->mode, "RGBA") == 0) { ImagingSectionEnter(&cookie); paste_mask_RGBA( imOut, imIn, imMask, dx0, dy0, sx0, sy0, xsize, ysize, pixelsize);