You are right that Agg is doing the resizing here.  Agg expects premultiplied alpha.  See [1] for information about what that means.


After Agg interpolates the pixel values, to prevent oversaturation it truncates all values to be less than alpha (which makes sense if everything is assumed to be premultiplied alpha).  Arguably, the bug here is that nearest neighbor (which doesn't have to do any blending) doesn't perform the truncation step -- then both would look "wrong".

It happens in this code snippet in span_image_filter_rgba: (base_mask is 255)

                if(fg[order_type::A] > base_mask)         fg[order_type::A] = base_mask;
                if(fg[order_type::R] > fg[order_type::A]) fg[order_type::R] = fg[order_type::A];
                if(fg[order_type::G] > fg[order_type::A]) fg[order_type::G] = fg[order_type::A];
                if(fg[order_type::B] > fg[order_type::A]) fg[order_type::B] = fg[order_type::A];

So, the solution to make a partially transparent image is to not do:

    pix[:,:,3] = 127

but instead, do

    pix *= 0.5

Of course, the real fix here is to support alpha blending properly in the image class, then the user wouldn't have to deal with such details.  A bug should probably be filed in the matplotlib issue tracker for this.


On 10/19/2011 12:23 PM, Daniel Hyams wrote:
[Sorry, I keep getting tripped up with HTML mail....resent in ascii,
and resaved one of the attachment png's to make it smaller.]

Example script attached (PIL required).  Basically, if I impose a
specific value into an image's alpha channel and use any interpolation
scheme other than 'nearest', there appears gray all where the figure
didn't have any color to begin with.   I've also attached a screenshot
of the output of the script on my machine.

Hopefully I'm doing something wrongly?

I chased the problem and managed to hack in a solution that fixes the
problem, but it's extremely inefficient...basically, in matplotlib's, routine BboxImage.make_image, you can create two images with no alpha channel (call it imRGB) and one with (call
it imRGBA).  Go through all of the routine, doing exactly the same
things to both of the images *except* for the interpolation, which is
set to 'nearest' for imRGBA.  Then, rip the colors out of imRGB, the
alpha channel off of imRGBA, and put them together....go through all
of the routine again with this composited image, and it works.  I
know...I told you it was bad ;)

The problem seems to be in the "resize" call in that routine...resize,
which calls into C code, does not appear to handle things correctly
when the alpha is anything other than 255's across the board.  It
might be a problem in the agg routines, but hopefully it is just maybe
a misuse of the agg routines.

The behavior seems to be backend independent as far as I could test (I
tried with wxagg and tk backends).  I am using mpl 1.0.0 on Windows if
it matters.

Daniel Hyams
------------------------------------------------------------------------------ All the data continuously generated in your IT infrastructure contains a definitive record of customers, application performance, security threats, fraudulent activity and more. Splunk takes this data and makes sense of it. Business sense. IT sense. Common sense.
_______________________________________________ Matplotlib-users mailing list