| Summary: | strange/wrong behavoiur when using cairo.ImageSurface.create_for_data with alpha values != 255 | ||
|---|---|---|---|
| Product: | pycairo | Reporter: | Tobias Bonnke <tobias.bonnke> |
| Component: | general | Assignee: | Steve Chaplin <d74n5pohf9> |
| Status: | RESOLVED NOTABUG | QA Contact: | |
| Severity: | normal | ||
| Priority: | medium | CC: | tobias.bonnke |
| Version: | unspecified | ||
| Hardware: | x86 (IA32) | ||
| OS: | Windows (All) | ||
| Whiteboard: | |||
| i915 platform: | i915 features: | ||
| Attachments: |
The "correctly" created gradient image which looks like expected
The "incorrectly" looking gradient image, the "unexpected/wrong" result so to say |
||
Created attachment 7998 [details]
The "correctly" created gradient image which looks like expected
Created attachment 7999 [details]
The "incorrectly" looking gradient image, the "unexpected/wrong" result so to say
This image should look like "channel_test_alpha_const.png", the only difference
should be that each scanline's alpha should increment from y=0, alpha=0 to
y=255, alpha=255. But instead the image is not a linear gradient at all.
This is a due to the format CAIRO_FORMAT_ARGB32 using pre-multiplied alpha.
That is, 50% transparent red is 0x80800000, not 0x80ff0000.
Something like this shound produce better results:
pelData = array.array('B', [0] * imgW * imgH * 4)
for y in range(imgH):
for x in range(imgW):
offset = (x + (y * imgW)) * 4
alpha = y
pelData[offset+0] = 0
pelData[offset+1] = 0
pelData[offset+2] = int((x * alpha)/255)
pelData[offset+3] = alpha
img = cairo.ImageSurface.create_for_data(pelData, cairo.FORMAT_ARGB32, imgW,
imgH, imgW * 4)
img.write_to_png("channel_test_alpha_var.png")
(But if its just gradients you want, cairo has its own functions to create
gradients)
|
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.
When using cairo.ImageSurface.create_for_data in order to create an image in cairo.FORMAT_ARGB32 using alpha-values != 255 the image contains wrong pixel data. Please create those two generated images (python 2.5 code using pycairo 1.2.6) in order to simplify the (follwing) problem-explanation: # ---- code snippet start ---- imgW = 255 imgH = 255 pelData = array.array('c', '\0x0' * imgW * imgH * 4) for y in range(imgH): for x in range(imgW): offset = 4 * ((y * imgW) + x) pelData[offset+0] = chr(0) # B pelData[offset+1] = chr(0) # G pelData[offset+2] = chr(x) # R pelData[offset+3] = chr(255) # A, when is CONSTANT=255 image is okay img = cairo.ImageSurface.create_for_data(pelData, cairo.FORMAT_ARGB32, imgW, imgH, imgW * 4) img.write_to_png("channel_test_alpha_const.png") pelData = array.array('c', '\0x0' * imgW * imgH * 4) for y in range(imgH): for x in range(imgW): offset = 4 * ((y * imgW) + x) pelData[offset+0] = chr(0) # B pelData[offset+1] = chr(0) # G pelData[offset+2] = chr(x) # R pelData[offset+3] = chr(y) # A, when varies image seems to be f*cked up img = cairo.ImageSurface.create_for_data(pelData, cairo.FORMAT_ARGB32, imgW, imgH, imgW * 4) img.write_to_png("channel_test_alpha_var.png") # ---- code snippet end ---- When executed, two images are created for illustrating the problem: - "channel_test_alpha_const.png" contains a gradient from black (left image border) to red (right image border), using 255 as constant alpha value for each pixel - ""channel_test_alpha_var.png"" SHOULD contain the same gradient as the one in the previous image, BUT: the alpha-value for each pixel-row is identical to it's y-index, means in top-most pixel row the gradient should be invisible due to alpha=0 and in the bottom-most row the gradient should be full saturated due to alpha=255 Due to some reason that's not true: the gradient-image using variable alpha values instead of a constant one looks totally different. This seems to be dependent to the alpha value: if alpha differs from 255 the image seems to have a "misaligned" stride depending on the alpha value or something like that. There are "gradient-like" edges in the image, always from top-left to some "bottom-right" angle. I hope the two test images illustrate the problem well, because it's difficult to explain it here. And I need to mention that on the one hand I'm new to Python (so it's possible I made some mistake creating the array), but on the other hand the only difference in the code is the byte I set for the alpha-values in each pixel's data, so I'm quite sure the problem must depend on the data I pass to the create_for_data method. Further (hopefully useful) information: - Win XP - Python 2.5 - pycairo 1.2.6