如何避免(PIL)imageQt 的奇怪行为?
how to avoid (PIL) imageQt's bizarre behaviour?
我用 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"))) 则图像正确显示。
问题
想要的结果:
我用正常 运行 得到的结果:
现在可以观察到三种情况:
- 只是 运行 代码(没有测试代码):显示了一个图形,但显然它是一块随机内存,尽管看起来总是一样。
- 调试代码,在setImage()中停止,并保存传入的图像:保存的文件和显示的图像都是正确的。
- 调试或 运行 行 image.save("r:/test.png") 未注释:然后 python 崩溃。
因此,我认为 ImageQt 中的某些内容已经烂掉,最终可能会得到纠正。奇怪的行为提醒了问题 Nick Morgan discusses,但只是将 imageQt 包裹在另一个 QImage 中并不能使情况变得更好。哦,是的,我在 Windows 下 运行ning。
此外:与 PIL Image to QPixmap conversion issue 没有任何联系,因为该问题是关于颜色通道的顺序,与 imageQt 中的虚假内存指针无关。
问题
是否有可用的替代转换方法(保存并读取作为解决方法?)?
可以推动 imageQt 表现得像它应该的那样(还是我自己做错了什么)?
Padraic Cunningham 解决了 Pillow (PIL) to QImage conversion -> python.exe has stopped working and offered a work-around. However, in his example code the colour bands get mixed up. That issue is answered by Jordan in pil-image to qpixmap conversion issue 中崩溃 python 的问题。所以最后,这个改编解决了我的问题:
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)
我用 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"))) 则图像正确显示。
问题
想要的结果:
我用正常 运行 得到的结果:
现在可以观察到三种情况:
- 只是 运行 代码(没有测试代码):显示了一个图形,但显然它是一块随机内存,尽管看起来总是一样。
- 调试代码,在setImage()中停止,并保存传入的图像:保存的文件和显示的图像都是正确的。
- 调试或 运行 行 image.save("r:/test.png") 未注释:然后 python 崩溃。
因此,我认为 ImageQt 中的某些内容已经烂掉,最终可能会得到纠正。奇怪的行为提醒了问题 Nick Morgan discusses,但只是将 imageQt 包裹在另一个 QImage 中并不能使情况变得更好。哦,是的,我在 Windows 下 运行ning。
此外:与 PIL Image to QPixmap conversion issue 没有任何联系,因为该问题是关于颜色通道的顺序,与 imageQt 中的虚假内存指针无关。
问题
是否有可用的替代转换方法(保存并读取作为解决方法?)?
可以推动 imageQt 表现得像它应该的那样(还是我自己做错了什么)?
Padraic Cunningham 解决了 Pillow (PIL) to QImage conversion -> python.exe has stopped working and offered a work-around. However, in his example code the colour bands get mixed up. That issue is answered by Jordan in pil-image to qpixmap conversion issue 中崩溃 python 的问题。所以最后,这个改编解决了我的问题:
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)