开发者

Convert PyQt to PIL image

I have an image in a QImage and I want to process it in PIL before I display it. While the ImageQT class lets me convert a PIL Image to a QImage, there doesn't appear to anything to go from a开发者_Go百科 QImage to a PIL Image.


I convert it from QImage to PIL with this code:

img = QImage("/tmp/example.png")
buffer = QBuffer()
buffer.open(QIODevice.ReadWrite)
img.save(buffer, "PNG")

strio = cStringIO.StringIO()
strio.write(buffer.data())
buffer.close()
strio.seek(0)
pil_im = Image.open(strio)

I tried many combinations before getting it to work.


#Code for converting grayscale QImage to PIL image

from PyQt4 import QtGui, QtCore
qimage1 = QtGui.QImage("t1.png")
bytes=qimage1.bits().asstring(qimage1.numBytes())
from PIL import Image
pilimg = Image.frombuffer("L",(qimage1.width(),qimage1.height()),bytes,'raw', "L", 0, 1)
pilimg.show()


Another route would be:

  1. Load the image data into a numpy array (example code using PIL)
  2. Manipulate the image using numpy, scipy or scikits.image
  3. Load the data into a QImage (example: browse the scikits.image archive (linked in 1) and look on line 45 of qt_plugin.py -- sorry, stackoverflow doesn't allow me to post more links yet)

As Virgil mentions, the data must be 32-bit (or 4-byte) aligned, which means you need to remember to specify the strides in step 3 (as shown in the snippet).


from PyQt5 import QtGui
from PIL import Image

img = QtGui.QImage(width, height, QImage.Format_RGBA8888)
data = img.constBits().asstring(img.byteCount())
pilimg = Image.frombuffer('RGBA', (img.width(), img.height()), data, 'raw', 'RGBA', 0, 1)
from PyQt4 import QtGui
from PIL import Image

img = QtGui.QImage("greyScaleImage.png")
bytes = img.bits().asstring(img.numBytes())
pilimg = Image.frombuffer('L', (img.width(), img.height()), bytes, 'raw', 'L', 0, 1)
pilimg.show()

Thanks Eli Bendersky, your code was helpful.


You can convert a QImage into a Python string:

>>> image = QImage(256, 256, QImage.Format_ARGB32)
>>> bytes = image.bits().asstring(image.numBytes())
>>> len(bytes)
262144

Converting from this to PIL should be easy.


Here is an answer for those using PySide2 5.x, the official python wrappings for qt. They should also work for PyQt 5.x

I also added to QImage to numpy that I've used in conjunction with this one. I prefer to use PIL dependency, mainly because I don't have to track color channel changes.

from PySide2 import QtCore, QtGui
from PIL import Image
import io


def qimage_to_pimage(qimage: QtGui.QImage) -> Image:
    """
    Convert qimage to PIL.Image

    Code adapted from SO:
    https://stackoverflow.com/a/1756587/7330813
    """
    bio = io.BytesIO()
    bfr = QtCore.QBuffer()
    bfr.open(QtCore.QIODevice.ReadWrite)
    qimage.save(bfr, 'PNG')
    bytearr = bfr.data()
    bio.write(bytearr.data())
    bfr.close()
    bio.seek(0)
    img = Image.open(bio)
    return img

Here is one to convert numpy.ndarray to QImage

from PIL import Image, ImageQt
import numpy as np

def array_to_qimage(arr: np.ndarray):
    "Convert numpy array to QImage"
    img = Image.fromarray(arr)
    return ImageQt.ImageQt(img)

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜