From e10cab42f1112645e1cf90b0e460e441e2682f1f Mon Sep 17 00:00:00 2001 From: Andrew Murray Date: Sun, 19 Apr 2020 20:56:17 +1000 Subject: [PATCH 1/2] Consider transparency when drawing text on an RGBA image --- Tests/images/transparent_background_text.png | Bin 0 -> 1271 bytes Tests/test_image_paste.py | 2 +- Tests/test_imagefont.py | 12 ++++++++++++ src/libImaging/Paste.c | 8 ++++++-- 4 files changed, 19 insertions(+), 3 deletions(-) create mode 100644 Tests/images/transparent_background_text.png diff --git a/Tests/images/transparent_background_text.png b/Tests/images/transparent_background_text.png new file mode 100644 index 0000000000000000000000000000000000000000..40acd92b62243953ebc0910629922eef112424e1 GIT binary patch literal 1271 zcmeAS@N?(olHy`uVBq!ia0y~yVAKJ!Q#jawqzxnQ0R{$^eV#6kAr*7p-j44O4V5|Y zaeb1ailSHjRfP~GB~2xzo}kkUbedi$F5RZ1(b?3*rNp7svT4Dmh4vy-_g?W1V_7;e zY(_>vOH{xk=T}*_SK8jW<>mdWvPi%A(d_%Zz5m^|yl3ZoWBdHfnf{&D&*y!fEjdBO za}p+6^4QZQB=niTwv<-&MP2Ou{8{s5{nOWKf8*HW zGCxZM1y7E8^Iy$?`3CEr=oRrSG0b-uY;MoJ&}Y56q4mJt1M_BWD=(VKx8~syTlfDA z?tP^KR)t%w4hJRwJ+OxD?Q@1|?XIU07Bjl92#4}U)E?M=ApQWu2RnoHi;}1B zTkga;NLBcqEKN0D6ZUwfzm!cG<8CN^u zp8GfV-G2EU8vkoqH?)@Yi9by~qjWZAm*Dx72dN31nPM!On)h@J@10nBVCs_h*(%rH zs@)B!klC^LM3zpYCY*4>VDmLH4X zdYnGXR=47^na|@0McY@K_O2H6WPPj0c|6-b)ACDYf4_0u?*>cWThA~2D-yW$CP}M6 z?}N5xrtiJyKbNH5DQNw;nn>+15746fXt6pX_wk>Vey(Vz1ESm%I2qEVmk!GpC1%cYTT9E4RUn zG5$%B?MtOOPP>A4G)+0YYr%0tk*|~GOmDbIIV^ipB>Xb(_T`d)bFSDukPG^kb*1Xk z+)KA+dW(MClBAota;Mx5o#RI4$19}W_umc3meO?GKl>A7#45i!^*6H*S!dqndf%0+ zbLG8W<@6lScg7Ne^=?P{Ix5tZo?ZDeTT0M5@P5L(%X$AVZqiUPdy?D!={~pg9_8y^ zmC8zWIxFwX3$A{hV|=eduW#{vZk=DcN@`cXze{AhWHL|?~z<)l;>pT3T@ wmAj{^ZuIT%u-)miK6g51E~c|cU;cllW|6Y9@p)IxfCUmdKI;Vst0LA-JqyPW_ literal 0 HcmV?d00001 diff --git a/Tests/test_image_paste.py b/Tests/test_image_paste.py index 1d3ca8135..3740fbcdc 100644 --- a/Tests/test_image_paste.py +++ b/Tests/test_image_paste.py @@ -236,7 +236,7 @@ class TestImagingPaste: [ (127, 191, 254, 191), (111, 207, 206, 110), - (127, 254, 127, 0), + (255, 255, 255, 0) if mode == "RGBA" else (127, 254, 127, 0), (207, 207, 239, 239), (191, 191, 190, 191), (207, 206, 111, 112), diff --git a/Tests/test_imagefont.py b/Tests/test_imagefont.py index 0e642cde2..b9dec9530 100644 --- a/Tests/test_imagefont.py +++ b/Tests/test_imagefont.py @@ -150,6 +150,18 @@ class TestImageFont: assert_image_equal(img_path, img_filelike) + def test_transparent_background(self): + im = Image.new(mode="RGBA", size=(300, 100)) + draw = ImageDraw.Draw(im) + ttf = self.get_font() + + txt = "Hello World!" + draw.text((10, 10), txt, font=ttf) + + target = "Tests/images/transparent_background_text.png" + with Image.open(target) as target_img: + assert_image_similar(im, target_img, 4.09) + def test_textsize_equal(self): im = Image.new(mode="RGB", size=(300, 100)) draw = ImageDraw.Draw(im) diff --git a/src/libImaging/Paste.c b/src/libImaging/Paste.c index 0bda25739..69353ce46 100644 --- a/src/libImaging/Paste.c +++ b/src/libImaging/Paste.c @@ -379,9 +379,13 @@ fill_mask_L(Imaging imOut, const UINT8* ink, Imaging imMask, UINT8* mask = (UINT8*) imMask->image[y+sy]+sx; for (x = 0; x < xsize; x++) { for (i = 0; i < pixelsize; i++) { - *out = BLEND(*mask, *out, ink[i], tmp1); - out++; + UINT8 channel_mask = *mask; + if (strcmp(imOut->mode, "RGBA") == 0 && i != 3) { + channel_mask = 255 - (255 - channel_mask) * (1 - (255 - out[3]) / 255); + } + out[i] = BLEND(channel_mask, out[i], ink[i], tmp1); } + out += pixelsize; mask++; } } From 9390e5636a21ef6dbd68f787eb975bf40b255fa9 Mon Sep 17 00:00:00 2001 From: Andrew Murray Date: Mon, 20 Apr 2020 18:53:37 +1000 Subject: [PATCH 2/2] Also consider other alpha modes --- src/libImaging/Paste.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/libImaging/Paste.c b/src/libImaging/Paste.c index 69353ce46..d0610cfc5 100644 --- a/src/libImaging/Paste.c +++ b/src/libImaging/Paste.c @@ -380,7 +380,13 @@ fill_mask_L(Imaging imOut, const UINT8* ink, Imaging imMask, for (x = 0; x < xsize; x++) { for (i = 0; i < pixelsize; i++) { UINT8 channel_mask = *mask; - if (strcmp(imOut->mode, "RGBA") == 0 && i != 3) { + if (( + strcmp(imOut->mode, "RGBa") == 0 || + strcmp(imOut->mode, "RGBA") == 0 || + strcmp(imOut->mode, "La") == 0 || + strcmp(imOut->mode, "LA") == 0 || + strcmp(imOut->mode, "PA") == 0 + ) && i != 3) { channel_mask = 255 - (255 - channel_mask) * (1 - (255 - out[3]) / 255); } out[i] = BLEND(channel_mask, out[i], ink[i], tmp1);