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

Composite semi-transparent avatars over a solid background #3874

Merged
merged 8 commits into from
Aug 8, 2023
Merged

Composite semi-transparent avatars over a solid background #3874

merged 8 commits into from
Aug 8, 2023

Conversation

nikclayton
Copy link
Contributor

Avatars that are semi-transparent are a problem when viewing a thread, as the line that connects different statuses in the same thread is drawn underneath the avatar and is visible.

Fix this with a CompositeWithOpaqueBackground Glide transformation that:

  1. Extracts the alpha channel from the avatar image
  2. Converts the alpha to a 1bpp mask
  3. Draws that mask on a new bitmap, with the appropriate background colour
  4. Draws the original bitmap on top of that

So any partially transparent areas of the original image are drawn over a solid background colour, so anything drawn under them will not appear.

Avatars that are semi-transparent are a problem when viewing a thread, as the line that connects different statuses in the same thread is drawn underneath the avatar and is visible.

Fix this with a CompositeWithOpaqueBackground Glide transformation that:

1. Extracts the alpha channel from the avatar image
2. Converts the alpha to a 1bpp mask
3. Draws that mask on a new bitmap, with the appropriate background colour
4. Draws the original bitmap on top of that

So any partially transparent areas of the original image are drawn over a solid background colour, so anything drawn under them will not appear.
@nikclayton
Copy link
Contributor Author

Before and after.

@nikclayton
Copy link
Contributor Author

However, something weird happens on account activities for the avatar image. Before and after again:

If you look closely, the avatar image in the screenshot on the right has some extra transparency on the right hand edge.

No idea what's causing it, I'm going to create a small reproduction and file a bug over at the Glide repository.

@nikclayton nikclayton marked this pull request as draft July 23, 2023 20:53
@nikclayton
Copy link
Contributor Author

Glide issue: bumptech/glide#5218

@mcclure
Copy link
Collaborator

mcclure commented Jul 23, 2023

I think as long as this method is efficient, this is done correctly except! In my opinion you should only do this in the regular view (when drawing over the line) and not in other places. Alpha of the sort in this avatar is most often used for feathering/anti-aliasing the edges of shapes. If you convert such edges to 1bpp and then draw them atop complex images (as you can see in the boost badge), you will tend to get gross looking "haloing". A little bit of this is visible here (a white line around the blue face shape). If this is okay in the case of the line shape, it is okay because you are the same color as the background and the background is uniform, so the "halo" is not visible (except where it touches the line, in which case it will only look like the line halting a pixel or three "early"

I am not sure I see what you refer to by "extra transparency on the right hand edge" in the profile view.
EDIT: I do see the problem in the glide issue. That's very strange

@nikclayton
Copy link
Contributor Author

@mcclure Please could you give it a try now. I've changed it so that the opaque background is only applied to the avatar image in the timeline (not on the profile page, or the small "reblog" icon, etc). That works around bumptech/glide#5218 for the moment.

Arguably it might make sense to include it on the reblog icon as well, as without it profiles like jernej__s are hard to distinguish, as is apparent on the first picture in #3874 (comment).

The haloing is (I think) because of paintShader.style = Paint.Style.FILL_AND_STROKE. That could be changed to FILL -- wdyt?

@nikclayton nikclayton marked this pull request as ready for review July 27, 2023 13:22
@nikclayton nikclayton requested review from Tak, connyduck and charlag and removed request for Tak July 27, 2023 13:22
@mcclure
Copy link
Collaborator

mcclure commented Jul 27, 2023

as without it profiles like jernej__s are hard to distinguish

I think this is acceptable, honestly— I have never seen another avatar like jernej__s's, and it seems like jernej is only doing it to be "difficult". If someone is doing something ~clever~ with the intention of causing an unusual effect, and it causes an unusual effect, I don't think we need to do anything. (Although I do think fixing the lines is nice, because in that case it appears to the user that Tusky is broken, rather than the avatar itself "looking weird")

This is especially because I believe any attempt to "fix" the reblog-icon case would have bad effects in other cases. In the usual case, where alpha is used to add anti-aliased edges, it adds the halo. But it also breaks some of the "being difficult" cases. Imagine if someone's avatar was a magnifying glass, and the "glass" were low-alpha blue so that whatever was underneath it would show with a blue tint. If we tried to force opacity, then this effect wouldn't work as intended…

The haloing is (I think) because of paintShader.style = Paint.Style.FILL_AND_STROKE. That could be changed to FILL -- wdyt?

I think the difference between FILL and FILL_AND_STROKE is not relevant to drawBitmap. The halo is inherent to how alpha is used in most images— it usually hugs the edges of a shape so that the shape will blend nicely with the color behind it. In the strategy above for forcing objects to be opaque, that information is lost when we do the drawBitmap: the alpha is thrown away and the edge pixels instead blend with the background color we chose. But then when you place this "opaqued" image on top of something of a different color from the background, like another avatar, then it will be blending to the wrong color. That's all the halo is— the avatar being surrounded by a group of lighter/darker pixels as it fades to white/black. But then when you composit for the reblog icon this looks like a ring of white/black around the avatar. You can't fix this, because it's "correct" to begin with. Not sure if I'm communicating this cleanly. I think I could make some demo PNGs if it helps…

@nikclayton
Copy link
Contributor Author

I think the difference between FILL and FILL_AND_STROKE

Ah, I think we're talking about two different things. I hadn't realised you meant a halo on the reblog button. I see a (possible) outline that's visible when the thread markers overlap with the avatar image.

With that in mind, I agree with everything you've said.

@nikclayton nikclayton requested review from mcclure and removed request for connyduck, Tak and charlag August 1, 2023 21:17
@nikclayton
Copy link
Contributor Author

nikclayton commented Aug 1, 2023

@mcclure - you should be able to approve PRs now, so if you wouldn't mind formally approving this that'd be great, cheers.

[The Bitrise CI failure is because they've failed to fetch a dependency, the build with Github actions is green]

@nikclayton nikclayton self-assigned this Aug 5, 2023
@mcclure
Copy link
Collaborator

mcclure commented Aug 6, 2023

Reviewed code, LGTM.

Also tested with 3892, saw no problems. (I did see #3934 but on testing, this also occurs on vanilla Tusky 23, so it is not a regression and should not hold back this PR.)

@nikclayton nikclayton merged commit 4169dc3 into tuskyapp:develop Aug 8, 2023
3 checks passed
@nikclayton nikclayton deleted the transparent-avatars-threads branch August 8, 2023 21:10
@charlag charlag added this to the Tusky 24 milestone Nov 18, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants