QGraphicsView 抗锯齿算法不适用于非常小的细节
QGraphicsView antialiasing algorithm doesn't work well with very small details
我在使用 QGraphicsView 时遇到的问题它显示的图像(Pillow 生成的图像)质量低,我无法阅读图像上的文字但是如果我缩放我可以更好地看到细节但是在它的全尺寸上它不清晰并且很失望。
这里有两个样本,一个是问题,另一个是应该解决的问题。
QGraphicsView场景质量问题
还有这个
从 windows 图像查看器打开相同尺寸的相同图像:
link 示例:https://imgur.com/a/JINAq4S
涵盖该问题的代码示例。
字体 link: https://gofile.io/d/dXesZv
from PyQt5 import QtWidgets, QtGui, QtCore, QtMultimedia
from PIL import Image, ImageDraw, ImageFont
from PIL.ImageQt import ImageQt
import os
class Main(QtWidgets.QWidget):
def __init__(self, parent=None):
super().__init__(parent)
#the image that would be viewed in QGraphicsView.
_fnt = ImageFont.truetype("ar.ttf" , 100)
_image = Image.new("RGBA", size=(2480, 3508), color="white")
_draw = ImageDraw.Draw(_image)
_draw.text((1000, 200), text="See See", fill="black", font=_fnt)
#QGraphicsView ...
_image.save("sample.png") ; os.startfile("sample.png") # to see what it should look like, like windows image viewer shows it.
self.result = ImageViewer(self, _image)
_layout = QtWidgets.QVBoxLayout()
_layout.addWidget(self.result)
self.setLayout(_layout)
class ImageViewer(QtWidgets.QGraphicsView):
def __init__(self, parent, image):
super(ImageViewer, self).__init__(parent)
self._scene = QtWidgets.QGraphicsScene(self)
qim = ImageQt(image)
self._pixmap = QtGui.QPixmap.fromImage(qim)
self._photo = QtWidgets.QGraphicsPixmapItem(self._pixmap)
self._scene.addItem(self._photo)
self.setScene(self._scene)
self.setBackgroundBrush(QtGui.QBrush(QtGui.QColor(230, 230, 230)))
def resizeEvent(self, event):
self.fitInView(self._photo, QtCore.Qt.KeepAspectRatio)
super().resizeEvent(event)
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
main = Main()
main.setWindowState(QtCore.Qt.WindowMaximized)
main.show()
app.exec_()
最终我想出了一个问题的答案:
问题是:
- QGraphicsView 对高分辨率图像的性能很差(无法读取图像中的小细节),因为抗锯齿算法不能很好地处理非常小的细节。
我尝试过,帮助但从未解决的问题:
- 我使用了 .setTransformationMode(QtCore.Qt.SmoothTransformation) 和 .setRenderHints(QtGui.QPainter.Antialiasing | QtGui.QPainter.HighQualityAntialiasing) 这很有帮助。
我给出的解决方案:
- 我将高分辨率图像的大小调整为较小的分辨率,这样可以看到高质量的图像,并且能够读取小文本等小细节。
我如何调整图片大小:-
- 场景中使用的图像是枕头对象,所以我使用了方法 .resize((int(image.size[0]/3.5), int(image.size[1]/3.5 )), Image.ANTIALIAS), 注意 1/3.5 比率是可选的。
我在使用 QGraphicsView 时遇到的问题它显示的图像(Pillow 生成的图像)质量低,我无法阅读图像上的文字但是如果我缩放我可以更好地看到细节但是在它的全尺寸上它不清晰并且很失望。
这里有两个样本,一个是问题,另一个是应该解决的问题。
QGraphicsView场景质量问题
还有这个
从 windows 图像查看器打开相同尺寸的相同图像: link 示例:https://imgur.com/a/JINAq4S
涵盖该问题的代码示例。 字体 link: https://gofile.io/d/dXesZv
from PyQt5 import QtWidgets, QtGui, QtCore, QtMultimedia
from PIL import Image, ImageDraw, ImageFont
from PIL.ImageQt import ImageQt
import os
class Main(QtWidgets.QWidget):
def __init__(self, parent=None):
super().__init__(parent)
#the image that would be viewed in QGraphicsView.
_fnt = ImageFont.truetype("ar.ttf" , 100)
_image = Image.new("RGBA", size=(2480, 3508), color="white")
_draw = ImageDraw.Draw(_image)
_draw.text((1000, 200), text="See See", fill="black", font=_fnt)
#QGraphicsView ...
_image.save("sample.png") ; os.startfile("sample.png") # to see what it should look like, like windows image viewer shows it.
self.result = ImageViewer(self, _image)
_layout = QtWidgets.QVBoxLayout()
_layout.addWidget(self.result)
self.setLayout(_layout)
class ImageViewer(QtWidgets.QGraphicsView):
def __init__(self, parent, image):
super(ImageViewer, self).__init__(parent)
self._scene = QtWidgets.QGraphicsScene(self)
qim = ImageQt(image)
self._pixmap = QtGui.QPixmap.fromImage(qim)
self._photo = QtWidgets.QGraphicsPixmapItem(self._pixmap)
self._scene.addItem(self._photo)
self.setScene(self._scene)
self.setBackgroundBrush(QtGui.QBrush(QtGui.QColor(230, 230, 230)))
def resizeEvent(self, event):
self.fitInView(self._photo, QtCore.Qt.KeepAspectRatio)
super().resizeEvent(event)
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
main = Main()
main.setWindowState(QtCore.Qt.WindowMaximized)
main.show()
app.exec_()
最终我想出了一个问题的答案:
问题是:
- QGraphicsView 对高分辨率图像的性能很差(无法读取图像中的小细节),因为抗锯齿算法不能很好地处理非常小的细节。
我尝试过,帮助但从未解决的问题:
- 我使用了 .setTransformationMode(QtCore.Qt.SmoothTransformation) 和 .setRenderHints(QtGui.QPainter.Antialiasing | QtGui.QPainter.HighQualityAntialiasing) 这很有帮助。
我给出的解决方案:
- 我将高分辨率图像的大小调整为较小的分辨率,这样可以看到高质量的图像,并且能够读取小文本等小细节。
我如何调整图片大小:-
- 场景中使用的图像是枕头对象,所以我使用了方法 .resize((int(image.size[0]/3.5), int(image.size[1]/3.5 )), Image.ANTIALIAS), 注意 1/3.5 比率是可选的。