Skip to content

RendererAgg.tostring_rgb merely truncates alpha #5336

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

Closed
mdboom opened this issue Oct 28, 2015 · 7 comments · Fixed by #25484
Closed

RendererAgg.tostring_rgb merely truncates alpha #5336

mdboom opened this issue Oct 28, 2015 · 7 comments · Fixed by #25484
Labels
backend: agg status: inactive Marked by the “Stale” Github Action
Milestone

Comments

@mdboom
Copy link
Member

mdboom commented Oct 28, 2015

As suggested #5324 (comment), it might be a good idea to have it actually blend onto some background color instead.

@cbreeden
Copy link

There is an algorithm for the solution found on stackoverflow http://stackoverflow.com/questions/2049230/convert-rgba-color-to-rgb, which agrees with the solution given on wikipedia. The solution can be easily modified for our case where our RGB values are from 0-255 as opposed to 0-1 as found in wikipedia:

//Destination = (Dr, Dg, Db)
//Source = (Sr, Sb, Sg, Sa)
//Background = (Br, Bg, Bb)

Dr = [(255 - Sa)*Br + Sa*Sr]/255
Dg = [(255 - Sa)*Bg + Sa*Sg]/255
Db = [(255 - Sa)*Bb + Sa*Sb]/255

I took a quick look at

//-------------------------------------------------color_conv_rgba32_rgb24
and it appears that we would have to create two template functions, one for aRGB like types and one for RGBa types, or add a new input to the template to be able to incorporate the alpha values into the formula.

Unfortunately there is no mechanism to specify the background color, which would require extending the Py wrapper to include an optional parameter for specifying the background color. But eitherway, it seems unlikely to hope for getting the proper figure.facecolor and axes.facecolor in their proper positions. By default using figure.facecolor (or savefig.facecolor for when saving) would probably be best.

@tacaswell
Copy link
Member

Should we just get rid of tostring_rgb all together? It looks like we use it in 2 demos and wxagg, which can use tostring_rgba and special case getting rid of the alpha if it really can not deal with it.

@cbreeden
Copy link

I don't know. I guess I had a hope that we could fix tostring_rgb to flatten with a background color for anytime matplotlib needed to interface with file formats that either doesn't support an alpha channel or supports only a boolean alpha channel (as does gif).

My first second impression was that we could solve #5335 by passing 24-bit RGB (flattened) to write_png when it is used as an intermediate fileformat for things that don't support an alpha channel, like most animations.

Looking at the source, it seems that simply passing a 3-dimensional array to write_png will default to 24-bit RGB algorithms:

case 3:

I thought that we could possibly add a kwarg to force RGB (as I believe the conversion has to be done here, or as an init variable to the renderer?) here:

def print_png(self, filename_or_obj, *args, **kwargs):
, which could force RGB by using something like a tostring_rgb, or really, a to_rgb_flattened or something to pass along to write_png.

I don't know, I'd have to trace through the steps some more as I'm still trying to learn how all of this works, and there probably is a better way.

@waleedka
Copy link

I just encountered this issue. I'm using tostring_rgb() to extract the pixels of multiple Figures and render them into one combined Figure. The result was really bad and it took me a long time to finally find out that the alpha channels are being removed.

I see this issue was opened in 2015, so clearly not many people are getting bitten by it. Is there another way that I'm missing to extract the pixels of a Figure (without saving it to a file and then loading the file)?

@anntzer
Copy link
Contributor

anntzer commented May 14, 2018

You can probably do something like buf = io.BytesIO(); fig.savefig(buf, format="rgba"); buf.getvalue().

@waleedka
Copy link

@anntzer Good idea. Solved the problem. Thanks!

@github-actions
Copy link

This issue has been marked "inactive" because it has been 365 days since the last comment. If this issue is still present in recent Matplotlib releases, or the feature request is still wanted, please leave a comment and this label will be removed. If there are no updates in another 30 days, this issue will be automatically closed, but you are free to re-open or create a new issue if needed. We value issue reports, and this procedure is meant to help us resurface and prioritize issues that have not been addressed yet, not make them disappear. Thanks for your help!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backend: agg status: inactive Marked by the “Stale” Github Action
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants