Weird bug causing alpha channel to be lost
Overdrivr opened this issue · comments
I'm facing a weird bug that causes alpha channel to be lost when converting a QImage produced by qimage2ndarray
to a QPixmap. Please consider the test case below:
import qimage2ndarray
import numpy as np
import sys
from PyQt5.QtWidgets import QApplication
from PyQt5.QtGui import QPixmap
# Required to construct QPixmap
app = QApplication(sys.argv)
def test_fails_alpha():
shp = (32, 64, 4)
arr = np.ones(shp).astype(np.uint8)
# Uncomment line below, and issue appears, no more alpha channel
#arr *= 255
img = qimage2ndarray.array2qimage(arr)
pixmap = QPixmap(img)
assert pixmap.hasAlpha()
The array that is being used to generate a QImage has 4 channels, therefore it must include an alpha channel after numpy->QImage conversion. And when converting QImage -> QPixmap, the alpha should also be there. This works with code above.
But what is so very strange is that if you uncomment line 14 (therefore stop multiplying the entire numpy array with a constant), the alpha channel is lost and the assert raises.
I'm totally lost here. As far as I understand numpy arrays, there is absolutely nothing here that should cause this behavior. Any clues ?
If your alpha channel is constant 255, you do not really have alpha, right? I believe Qt may just interpret this as "no alpha" – at least, IIRC when loading images from disk, it becomes impossible to find out whether there was a completely opaque alpha channel or none at all.
Does that help? You might want to check the documentation and the return value of pixmap.hasAlphaChannel()
and img.hasAlpha()
as well.
Thanks for the reply. Looks like you're right, setting an arbitrary pixel to another value, such as arr[0, 0, -1] = 0
, fixes the issue.
However I'm wondering, is this behavior coming from Qt5 or qimage2ndarray ?
For float data, I agree that a constant value cannot be interpreted, but in this case data is uint8 and conventionally an alpha of 255 means fully opaque.
And in any case, the pixmap should get an alpha layer, even if fully opaque, because down the road the pixmap might be edited (alpha layer included).
I think it comes from Qt, as you can confirm by checking the code. To verify, I suggest to create a QImage with one pixel value set to 0, then set it to 255 on the QImage (after conversion), then create the QPixmap.
Looks like it's coming from Qt. I can reproduce without your lib.
What a bad behavior, very un-pythonic.
Thanks for your time and help, I'm going to close this since it has nothing to do with your lib ;)