Bug 50985

Summary: the alpha channel does not seem to work properly on windows
Product: pycairo Reporter: Michel Sanner <msd5112>
Component: generalAssignee: Steve Chaplin <d74n5pohf9>
Status: RESOLVED FIXED QA Contact:
Severity: major    
Priority: medium    
Version: unspecified   
Hardware: Other   
OS: Windows (All)   
Whiteboard:
i915 platform: i915 features:
Attachments: image illustrating the problem

Description Michel Sanner 2012-06-11 18:21:21 UTC
Created attachment 62907 [details]
image illustrating the problem

I wrote a sinple little script that draws a red rectangle on a Tkinter canvas and then creates 10 blue rectangles with opacity ranging from 0.0 tp 1.0 and draw them over the red rectangle.

I draw the blue rectangle twice. Overlaping with the top of the red bar the
blue rectangles are created using Image.frombuffer() while the ones overlaping
with the bottom of the red bar are created by saving and re-reading a .png file.

The program work fin under linux and Max OS X (see attached top part of attached image) but under windows I get strange results (see lower part of attached image). When I create the PIL image from the buffer it seems that low opacity values make the blue color darker instead of transparent and when
I write the image to file and re-read it (lower row of blue triangle) the opacity is either 0.0 (completely transparent) or 1.0 (opaque) (see bug.png).

Thanks for any help with that

-Michel

code:

import cairo

def rectangle(w, h, alpha):
    w = 20
    h = 20
    surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, w, h)
    ctx = cairo.Context(surface)

    # on windows this is bgr
    ctx.set_source_rgba(0,0,1,alpha)
    ctx.rectangle( 0, 0, w, h)
    ctx.fill_preserve()
    ctx.set_source_rgba(0,0,0,1)
    ctx.set_line_width(4)
    ctx.stroke()
    return surface

import Tkinter
root = Tkinter.Tk()
canvas = Tkinter.Canvas(root)

# draw a red bar
canvas.create_rectangle( 12, 12, 300, 35, fill='red')

# draw rectangles built with cairo
import Image, ImageTk
w = h = 20
ref = []
for i in range(0,11):
    alpha = i/10.0
    print i, alpha
    surface = rectangle(20, 20, alpha)
    # place square overlaping with top of red bar
    buf = surface.get_data()
    image = Image.frombuffer('RGBA', (w, h), buf, 'raw', 'BGRA', 0, 1)
    imagetk = ImageTk.PhotoImage(image=image)
    ref.append(imagetk)
    barid = canvas.create_image(2+i*25, 2, anchor=Tkinter.NW, image=imagetk)

    # place square overlaping with bottom of red bar
    surface.write_to_png('bar.png')
    image1 = Image.open('bar.png')
    imagetk1 = ImageTk.PhotoImage(image=image1)
    ref.append(imagetk1)
    barid = canvas.create_image(2+i*25, 25, anchor=Tkinter.NW, image=imagetk1)
   

canvas.pack()
Comment 1 Steve Chaplin 2012-08-04 05:44:30 UTC
Its hard to diagnose the problem since you are using pycairo and PIL and Tkinter.
What makes you think it is a pycairo problem and not a PIL or Tkinter problem?
If you can eliminate the Tkinter and PIL code and generate a smaller pycairo-only test case, that would make it much easier to see what is going on. Otherwise your program could just be demonstrating some quirk of PIL or Tkinter.
Comment 2 Christoph Reiter 2017-07-05 15:30:17 UTC
I've tried the example under MSYS2 and it works fine here. Maybe the problem was fixed int the meantime.

Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.