【问题标题】:PIL Image to QPixmap conversion issuePIL Image 到 QPixmap 的转换问题
【发布时间】:2016-04-14 08:19:19
【问题描述】:

今天我一直在努力应对这一挑战,我已经设法利用以前的帖子和其他资源获得了一个好点。

我正在尝试将 PIL.Image 转换为 QPixmap,以便可以在 PyQT GUI 上使用 QgraphicsScene 进行显示。但是,当显示图片时,颜色发生了变化?有没有人遇到过这个问题?

我使用的代码如下。

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

我在 windows 7 64bit 上,使用 python 3.4 和 PyQt4 和枕头 3.1.0。我得到的结果如下所示。

原图

图形界面显示

提前致谢:)。

【问题讨论】:

    标签: python pyqt pyqt4 python-imaging-library pillow


    【解决方案1】:

    在您的 PIL 图像中,最后一个波段是 alpha 通道,而在 Qt 图像中,alpha 通道是第一个(RGBA 与 ARGB)。可能还有其他方法可以置换波段,但最简单的方法似乎是使用 ImageQt 类。

    from PIL.ImageQt import ImageQt
    qim = ImageQt(im)
    pix = QtGui.QPixmap.fromImage(qim)
    

    【讨论】:

    • 正如@Michael 在他的回答中提到的那样,这会崩溃,例如使用 Win10/Python3.7.4/PyQt5,任何想法为什么以及如何轻松修复它而不是使用 Michael 冗长的解决方法?
    • 嗨@theozh。我不知道,但我没有参与 Pillow 项目,所以我不是要问的人。我建议在Pillow issue list on GitHub 中提交错误报告。确保包含复制错误消息和完整的堆栈跟踪。
    【解决方案2】:

    我不知道为什么,但是 ImageQt 在我的系统 Win10、Python3、Qt5 中崩溃了。 所以我去了另一个方向并尝试了在 github 上找到的解决方案。 此代码不会崩溃,但会产生第一篇文章中显示的效果。

    对此我的解决方案是,将 RGB 图片与每种颜色分开并将其组装为 BGR 或 BGRA,然后再将其转换为 Pixmap

        def pil2pixmap(self, im):
    
        if im.mode == "RGB":
            r, g, b = im.split()
            im = Image.merge("RGB", (b, g, r))
        elif  im.mode == "RGBA":
            r, g, b, a = im.split()
            im = Image.merge("RGBA", (b, g, r, a))
        elif im.mode == "L":
            im = im.convert("RGBA")
        # Bild in RGBA konvertieren, falls nicht bereits passiert
        im2 = im.convert("RGBA")
        data = im2.tobytes("raw", "RGBA")
        qim = QtGui.QImage(data, im.size[0], im.size[1], QtGui.QImage.Format_ARGB32)
        pixmap = QtGui.QPixmap.fromImage(qim)
        return pixmap
    

    【讨论】:

    • ImageQt 也不适用于 PySide2,所以这个解决方法就像一个魅力。
    【解决方案3】:

    我测试过RGB,PIL保存数据为qt格式Format_RGB888

    im = im.convert("RGB")
    data = im.tobytes("raw","RGB")
    qim = QtGui.QImage(data, im.size[0], im.size[1], QtGui.QImage.Format_RGB888)
    

    我还没有测试过,但我认为对于 RGBA,它将是等效格式 Format_RGBA8888:

    im = im.convert("RGBA")
    data = im.tobytes("raw","RGBA")
    qim = QtGui.QImage(data, im.size[0], im.size[1], QtGui.QImage.Format_RGBA8888)
    

    【讨论】:

    • RGBA(第二个)对我有用,而第一个则不行。
    【解决方案4】:

    这可能有用

    从 PIL Image 对象创建一个 ImageQt 对象。该类是 QtGui.QImage 的子类,这意味着您可以将生成的对象直接传递给 PyQt4/5 API 函数和方法。 模式 1、L、P、RGB 和 RGBA 图像当前支持此操作。要处理其他模式,需要先转换图像。

    https://pillow.readthedocs.io/en/stable/reference/ImageQt.html

    【讨论】:

      【解决方案5】:

      @titusjan 的回答对我不起作用。 @Michael 和 @Jordan 都有有效的解决方案。 @Michael 的一个更简单的版本只是重新定义如何为图像写入字节。所以这对我有用:

      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)
      

      唯一的区别是我交换了编码的顺序,例如到“BGRA”而不是“RGBA”。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-04-13
        • 1970-01-01
        • 1970-01-01
        • 2023-03-13
        • 2017-12-20
        • 1970-01-01
        相关资源
        最近更新 更多