pytroll / pytroll/aggdraw

Brush/Pen transparency weirdness

Open
#16 15 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug help wanted
Dominant language
C++
Stars
107
Forks
45
Avg merge
13h 41m
Merged PRs (30d)
7

Description

For various reasons, I've been using a pretty hacky method for applying transparency to aggdraw-drawn textures to surfaces in the Python package I maintain. This consisted of slicing off the 'A' value of any RGBA colours, creating a Brush and/or Pen with full opacity, and then applying the transparency value manually to the 'A' value for each pixel in the image using numpy. Last week, however, I figured out a way to fix the underlying problem that necessitated this workaround and decided to remove it and start using the regular Brush/Pen opacity values.

Much to my surprise, however, this produced dramatically different (and wrong) results. See the following two images:

screen shot 2018-01-11 at 10 58 54 am

screen shot 2018-01-11 at 11 04 32 am

In both images, the semi-transparent circle over the '6' is supposed to have a fill value of (192, 192, 192, 128). The first is done with the old numpy transparency hack, the second with an aggdraw Brush. As you can see, the aggdraw one is considerably darker than it should be.

Curious, I tried playing around with the Pillow image context aggdraw is drawing to, and sure enough, the fill colour of the fully transparent background affects the resulting colour of the aggdraw-drawn circle. For example, when setting opacity with aggdraw, drawing on a background with (255, 255, 255, 0) fill results in an actual fill (printing out the the pixel values to terminal) of (223, 223, 223, 127), whereas drawing on a background of (0, 0, 0, 0) fill results in an actual fill of (95, 95, 95, 127). When using the Numpy hack, it results in a background of (192, 192, 192, 128) regardless of what colour the transparent background fill has.

I'm guessing what's happening here is that aggdraw is trying to make up the difference between the background colour and the Brush colour as if it were an RGB surface without alpha, resulting in double-opacity. Is this something that's a quick fix in aggdraw, or is it a problem with the underling AGG library itself? I'd try my hand at a fix, but I have a lot on my plate programming-wise right now and I'm not too experienced in C.

Thanks in advance!

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

No files or tests are named. Start by reproducing the Brush/Pen opacity behavior on transparent backgrounds with different RGB values, then trace the aggdraw and underlying AGG drawing path. Done means semi-transparent RGBA fills produce the same expected color regardless of the transparent background color, with regression coverage added where the project’s existing tests belong.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp, python
Domain
computer-graphics
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
30/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.