Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PIL Image to QPixmap conversion issue

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 :).

like image 994
Pys3nberg Avatar asked Jan 09 '16 18:01

Pys3nberg


People also ask

How do you convert QImage to QPixmap?

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.

How do I save a PIL library image?

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.

How do I add a picture to another picture on PIL?

Image. Image. paste() method is used to paste an image on another image.

How do I open an image from PIL?

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).


2 Answers

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)
like image 143
titusjan Avatar answered Oct 13 '22 13:10

titusjan


@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'.

like image 33
Levi Avatar answered Oct 13 '22 13:10

Levi