Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix incorrect color blending for overlapping glyphs #7497

Merged
Merged
Changes from 6 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
f97570f
Blend colors with alpha when pasting
ZachNagengast Oct 27, 2023
49fd211
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 27, 2023
76f758e
Merge branch 'main' into fix-alpha-for-overlapping-glyphs
radarhere Oct 27, 2023
bb0eff4
Update blending logic
ZachNagengast Nov 3, 2023
a7f805d
Merge branch 'fix-alpha-for-overlapping-glyphs' of ssh://github.com/Z…
ZachNagengast Nov 3, 2023
e1aaec3
Merge branch 'main' of ssh://github.com/python-pillow/Pillow into fix…
ZachNagengast Nov 3, 2023
b15b2d4
Update src/_imagingft.c
ZachNagengast Nov 7, 2023
fdecfca
Update gray glyph blending logic and tests
ZachNagengast Nov 7, 2023
8ecf2e9
Merge branch 'fix-alpha-for-overlapping-glyphs' of ssh://github.com/Z…
ZachNagengast Nov 7, 2023
11bea8f
Merge branch 'main' of ssh://github.com/python-pillow/Pillow into fix…
ZachNagengast Nov 7, 2023
d127600
Update test images for overlapping text
ZachNagengast Nov 7, 2023
0a33b30
Update caron_below_ttb test image
ZachNagengast Nov 12, 2023
29ca3fc
Update caron_below_ttb_lb test image
ZachNagengast Nov 12, 2023
f3b3442
add test for glyph alpha blending
nulano Nov 27, 2023
0cef9f2
fix drawing text alpha on RGBA image on big-endian platforms
nulano Nov 27, 2023
38992f6
Merge pull request #1 from nulano/fix-alpha-for-overlapping-glyphs
ZachNagengast Nov 27, 2023
9c60e85
Apply suggestions from code review
ZachNagengast Nov 27, 2023
78f78d2
Update src/_imagingft.c
ZachNagengast Nov 28, 2023
e800026
Update Tests/test_imagefont.py
ZachNagengast Dec 1, 2023
bd2977c
Update src/PIL/ImageDraw.py
ZachNagengast Dec 2, 2023
a6a612c
Merge branch 'main' into fix-alpha-for-overlapping-glyphs
radarhere Dec 2, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
36 changes: 27 additions & 9 deletions src/_imagingft.c
Expand Up @@ -1049,6 +1049,7 @@
int k;
unsigned char v;
ZachNagengast marked this conversation as resolved.
Show resolved Hide resolved
unsigned char *target;
unsigned int tmp;
if (color) {
/* target[RGB] returns the color, target[A] returns the mask */
/* target bands get split again in ImageDraw.text */
Expand All @@ -1059,15 +1060,32 @@
if (color && bitmap.pixel_mode == FT_PIXEL_MODE_BGRA) {
/* paste color glyph */
for (k = x0; k < x1; k++) {
if (target[k * 4 + 3] < source[k * 4 + 3]) {
/* unpremultiply BGRa to RGBA */
target[k * 4 + 0] = CLIP8(
(255 * (int)source[k * 4 + 2]) / source[k * 4 + 3]);
target[k * 4 + 1] = CLIP8(
(255 * (int)source[k * 4 + 1]) / source[k * 4 + 3]);
target[k * 4 + 2] = CLIP8(
(255 * (int)source[k * 4 + 0]) / source[k * 4 + 3]);
target[k * 4 + 3] = source[k * 4 + 3];
int src_alpha = source[k * 4 + 3];
ZachNagengast marked this conversation as resolved.
Show resolved Hide resolved

/* paste only if source has data */
if (src_alpha > 0) {
/* unpremultiply RGBA */
int src_red = CLIP8((255 * (int)source[k * 4 + 0]) / src_alpha);
int src_grn = CLIP8((255 * (int)source[k * 4 + 1]) / src_alpha);
int src_blu = CLIP8((255 * (int)source[k * 4 + 2]) / src_alpha);
ZachNagengast marked this conversation as resolved.
Show resolved Hide resolved

/* blend required if target has data */
if (target[k * 4 + 3] > 0) {
/* blend colors to BGRa */
target[k * 4 + 0] = BLEND(src_alpha, target[k * 4 + 0], src_blu, tmp);
target[k * 4 + 1] = BLEND(src_alpha, target[k * 4 + 1], src_grn, tmp);
target[k * 4 + 2] = BLEND(src_alpha, target[k * 4 + 2], src_red, tmp);

Check warning on line 1077 in src/_imagingft.c

View check run for this annotation

Codecov / codecov/patch

src/_imagingft.c#L1075-L1077

Added lines #L1075 - L1077 were not covered by tests
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think these could be PREBLEND if you use the premultiplied source values. I'm not entirely certain whether that would require CLIP8 as well.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried PREBLEND with CLIP8
image

and without CLIP8
image

It seems like they're getting some artifacts in the areas with alpha, what do you think?

Here is just BLEND for reference:
image


/* blend alpha */
int out_alpha = CLIP8(src_alpha + MULDIV255(target[k * 4 + 3], (255 - src_alpha), tmp));
target[k * 4 + 3] = out_alpha;
ZachNagengast marked this conversation as resolved.
Show resolved Hide resolved
} else {

Check warning on line 1082 in src/_imagingft.c

View check run for this annotation

Codecov / codecov/patch

src/_imagingft.c#L1080-L1082

Added lines #L1080 - L1082 were not covered by tests
/* paste source directly to BGRa */
ZachNagengast marked this conversation as resolved.
Show resolved Hide resolved
target[k * 4 + 0] = src_blu;
target[k * 4 + 1] = src_grn;
target[k * 4 + 2] = src_red;
target[k * 4 + 3] = src_alpha;
ZachNagengast marked this conversation as resolved.
Show resolved Hide resolved
}
}
}
} else if (bitmap.pixel_mode == FT_PIXEL_MODE_GRAY) {
Expand Down