I've been struggling with this challenge for the best of today, I've managed to get a good point using previous posts and other resources.
I'm trying to convert a PIL.Image to a QPixmap so that I can display using a QgraphicsScene on my PyQT GUI. However when the picture is displayed the colours have changed?? Has anyone ever experienced this issue?
The code I use for this is as below.
self.graphicsScene.clear()
im = Image.open('Penguins.jpg')
im = im.convert("RGBA")
data = im.tobytes("raw","RGBA")
qim = QtGui.QImage(data, im.size[0], im.size[1], QtGui.QImage.Format_ARGB32)
pix = QtGui.QPixmap.fromImage(qim)
self.graphicsScene.addPixmap(pix)
self.graphicsView.fitInView(QtCore.QRectF(0,0,im.size[0], im.size[1]), QtCore.Qt.KeepAspectRatio)
self.graphicsScene.update()
Im on windows 7 64bit, using python 3.4 with PyQt4 and pillow 3.1.0. The results im getting can be seen below.
Original picture
Picture displayed in GUI
Thanks in advance :).
A QPixmap object can be converted into a QImage using the toImage() function. Likewise, a QImage can be converted into a QPixmap using the fromImage(). If this is too expensive an operation, you can use QBitmap::fromImage() instead.
save() Saves this image under the given filename. If no format is specified, the format to use is determined from the filename extension, if possible. Keyword options can be used to provide additional instructions to the writer.
Image. Image. paste() method is used to paste an image on another image.
Image. open() Opens and identifies the given image file. This is a lazy operation; this function identifies the file, but the file remains open and the actual image data is not read from the file until you try to process the data (or call the load() method).
In your PIL image the last band is the alpha channel, whereas in the Qt image the alpha channel is the first (RGBA vs. ARGB). There may be other ways of permuting the bands but the easiest way seems to use the ImageQt class.
from PIL.ImageQt import ImageQt
qim = ImageQt(im)
pix = QtGui.QPixmap.fromImage(qim)
@titusjan's answer didn't work for me. Both @Michael and @Jordan have solutions that worked. A simpler version of @Michael's is just to redefine how the bytes are written for the image. So this works for me:
im2 = im.convert("RGBA")
data = im2.tobytes("raw", "BGRA")
qim = QtGui.QImage(data, im.width, im.height, QtGui.QImage.Format_ARGB32)
pixmap = QtGui.QPixmap.fromImage(qim)
The only difference is that I swapped the order for the encoding, e.g. to 'BGRA' instead of 'RGBA'.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With