python - 如何避免(PIL)imageQt 的奇怪行为?
问题描述
我使用 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") uncommented行:然后 python 崩溃。
所以,我认为ImageQt中有些东西已经腐烂,最终可能会得到纠正。奇怪的行为让人想起Nick Morgan 讨论的问题,但只是将imageQt包装在另一个QImage中并不会改变这种情况。哦,是的,我在 Windows 下运行。
此外:与PIL Image 到 QPixmap 的转换问题没有任何联系,因为该问题与颜色通道的顺序有关,与 imageQt 中的虚假内存指针无关。
问题
是否有可用的替代转换方法(保存和读取作为解决方法?)?
可以推动 imageQt 表现得像它应该的那样(或者我自己做错了什么)?
解决方案
Padraic Cunningham解决了将Pillow (PIL) 中的 python 崩溃到 QImage 转换的问题 -> python.exe 已停止工作并提供了解决方法。然而,在他的示例代码中,色带混淆了。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)
推荐阅读
- excel - MSBI Merge:如何将 Excel 文件与 SSIS 中的测试文件合并?
- python - 获取streamlit中上传文件的原名
- azure - 如何从事件网格中获取成功部署 Azure 模板的事件
- c# - 如何在检查器中创建文本/字符串容器以添加描述/信息文本以及如何适应并将其转换为 ui 文本组件?
- python - 什么是实现图像跟随光标快速移动的好方法?
- amazon-web-services - 为什么我的 aws-cli 构建在构建时可以在中间容器上工作,但不能在最终容器上工作?
- java - 为什么 startActivityForResult 没有显示在回收器视图适配器中?
- swift - SwiftUI AnyTransition.animation 在使用 .offset 时不会覆盖动画参数
- javascript - 如何从 React Element 获取我的 React 组件对象
- jquery - 选择选项不可选择 - Jquery 自动完成