如何避免(PIL)imageQt的怪异行为?

时间:2019-06-10 20:06:13

标签: python pyqt python-imaging-library qimage

我使用PIL进行图像镶嵌,并希望使用 QGraphicsView 查看结果。为此,我将QtImageViewer子类化。那里的相关方法

def setImage(self, image):
    """ Set the scene's current image pixmap to the input QImage or QPixmap.
    Raises a RuntimeError if the input image has type other than QImage or QPixmap.
    :type image: QImage | QPixmap
    """
#    image.save("r:/test.png")
    if isinstance(image, QPixmap):
        pixmap = image
    elif isinstance(image, QImage):
        pixmap = QPixmap.fromImage(image)
    else:
        raise RuntimeError("ImageViewer.setImage: Argument must be a QImage or QPixmap.")

    if self.hasImage():
        self._pixmapHandle.setPixmap(pixmap)
    else:
        self._pixmapHandle = self.scene.addPixmap(pixmap)
    self.setSceneRect(QRectF(pixmap.rect()))  # Set scene size to image size.
    self.updateViewer()

我从其子类发出的调用显示为:

    def redraw(self):
        img = Image.new("RGB", (self.width(), self.height()), "gray")
        if self._source is not None:
            self._source.paintMap(img)
        img.save("r:/debug.png")
#         self.setImage(QImage("r:\debug.png"))
        self.setImage(ImageQt(img))

两个片段中都有测试代码行,可将图像内容保存到临时文件中。当我保存PIL图像( img.save(“ r:/debug.png”))并从该文件创建 QImage self.setImage( QImage(“ r:\ debug.png”)))即可正确显示图像。

问题

所需结果: enter image description here

我正常运行时得到的结果: enter image description here

现在可以观察到三种情况:

  1. 只运行代码(没有测试代码):显示了一个图形,但显然它是一块随机存储器,尽管看起来总是一样。
  2. 调试代码,将其停在 setImage ()中,然后保存传入的图像:保存的文件和显示的图像都是正确的。
  3. 调试或运行 image.save(“ r:/test.png”)注释:然后python崩溃。

所以,我认为 ImageQt 中有些东西烂了,最终可以纠正。奇怪的行为提醒了问题Nick Morgan discusses,但仅将 imageQt 包装在另一个 QImage 中并不能使情况变好。哦,是的,我正在Windows下运行。

此外:与PIL Image to QPixmap conversion issue 毫无关系,因为该问题与颜色通道的顺序有关,并且与imageQt中的虚假内存指针无关。

问题

  • 是否可以使用另一种转换方法(另存为替代方法?)?

  • 是否可以使imageQt表现为应有的状态(或者我自己做错了什么)?

1 个答案:

答案 0 :(得分:0)

Padraic Cunningham 解决了Pillow (PIL) to QImage conversion -> python.exe has stopped working中的python崩溃问题,并提供了一种解决方法。但是,在他的示例代码中,色带混杂在一起。 {strong> Jordan 在pil-image to qpixmap conversion issue中回答了该问题。所以最后,这种调整解决了我的问题:

def redraw(self):
    img = Image.new("RGB", (self.width(), self.height()), "gray")
    if self._source is not None:
        self._source.paintMap(img)
    data = img.convert("RGB").tostring("raw", "RGB")
    qimg = QImage(data, img.size[0], img.size[1], QImage.Format_RGB888)
    self.setImage(qimg)