From e98469ecf6ad2b93afc1481e1ebb90bb5af3acc3 Mon Sep 17 00:00:00 2001 From: Andrew Murray Date: Mon, 25 Jun 2018 21:08:41 +1000 Subject: [PATCH] Added transparency to matrix conversion --- Tests/test_image_convert.py | 3 +++ src/PIL/Image.py | 21 ++++++++++++++++++--- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/Tests/test_image_convert.py b/Tests/test_image_convert.py index 1e208d80c..84c1cc82e 100644 --- a/Tests/test_image_convert.py +++ b/Tests/test_image_convert.py @@ -187,6 +187,7 @@ class TestImageConvert(PillowTestCase): def matrix_convert(mode): # Arrange im = hopper('RGB') + im.info['transparency'] = (255, 0, 0) matrix = ( 0.412453, 0.357580, 0.180423, 0, 0.212671, 0.715160, 0.072169, 0, @@ -203,9 +204,11 @@ class TestImageConvert(PillowTestCase): target = Image.open('Tests/images/hopper-XYZ.png') if converted_im.mode == 'RGB': self.assert_image_similar(converted_im, target, 3) + self.assertEqual(converted_im.info['transparency'], (105, 54, 4)) else: self.assert_image_similar(converted_im, target.getchannel(0), 1) + self.assertEqual(converted_im.info['transparency'], 105) matrix_convert('RGB') matrix_convert('L') diff --git a/src/PIL/Image.py b/src/PIL/Image.py index f13a98276..e31d9002d 100644 --- a/src/PIL/Image.py +++ b/src/PIL/Image.py @@ -900,12 +900,28 @@ class Image(object): if not mode or (mode == self.mode and not matrix): return self.copy() + has_transparency = self.info.get('transparency') is not None if matrix: # matrix conversion if mode not in ("L", "RGB"): raise ValueError("illegal conversion") im = self.im.convert_matrix(mode, matrix) - return self._new(im) + new = self._new(im) + if has_transparency and self.im.bands == 3: + transparency = new.info['transparency'] + + def convert_transparency(m, v): + v = m[0]*v[0] + m[1]*v[1] + m[2]*v[2] + m[3]*0.5 + return max(0, min(255, int(v))) + if mode == "L": + transparency = convert_transparency(matrix, transparency) + elif len(mode) == 3: + transparency = tuple([ + convert_transparency(matrix[i*4:i*4+4], transparency) + for i in range(0, len(transparency)) + ]) + new.info['transparency'] = transparency + return new if mode == "P" and self.mode == "RGBA": return self.quantize(colors) @@ -913,8 +929,7 @@ class Image(object): trns = None delete_trns = False # transparency handling - if "transparency" in self.info and \ - self.info['transparency'] is not None: + if has_transparency: if self.mode in ('L', 'RGB') and mode == 'RGBA': # Use transparent conversion to promote from transparent # color to an alpha channel.