微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何更好地实现缩放图像?

如何解决如何更好地实现缩放图像?

我有以下代码

from PyQt5.QtWidgets import QWidget,QHBoxLayout,QVBoxLayout,QPushButton,qgroupbox,QLabel
from PyQt5.QtGui import Qpixmap
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.QtCore import Qt
import sys

class Window(QWidget):
    def __init__(self):
        super().__init__()

        self.imgLabel = QLabel(self)
        pixmap = Qpixmap("Feedreader.jpg")
        self.imgLabel.setpixmap(pixmap)
        self.imgLabel.setAlignment(Qt.AlignCenter | Qt.AlignCenter)
        self.imgLabel.setSizePolicy(QSizePolicy.Ignored,QSizePolicy.Ignored)

        scroll = QScrollArea()
        scroll.setWidget(self.imgLabel)
        scroll.setWidgetResizable(True)
        scroll.setFrameShape(qframe.NoFrame)

        self.zoomInButton = QPushButton('Zoom In',self)
        self.zoomInButton.clicked.connect(self.onZoomIn)

        self.zoomOutButton = QPushButton('Zoom Out',self)
        self.zoomOutButton.clicked.connect(self.onZoomOut)
    self.buttonGroup = qgroupbox()
        vBoxButtons = QVBoxLayout()
        vBoxButtons.addWidget(self.zoomInButton)
        vBoxButtons.addWidget(self.zoomOutButton)
        vBoxButtons.addStretch()
        self.buttonGroup.setLayout(vBoxButtons)

        self.hBox = QHBoxLayout()
        self.hBox.addWidget(scroll)
        self.hBox.addWidget(self.buttonGroup)
        self.setLayout(self.hBox)
        self.init()
        self.show()

    def init(self):

        self.scaleFactor = 1.0

    def onZoomIn(self):
        self.scaleImage(1.25)

    def onZoomOut(self):
        self.scaleImage(0.8)

    def scaleImage(self,factor):
        self.scaleFactor *= factor
        pm = self.imgLabel.pixmap()
        x = pm.width() * self.scaleFactor
        y = pm.width() * self.scaleFactor
        if x > 0 and y > 0:
            pm = pm.scaled(x,y,Qt.KeepAspectRatio)

            self.imgLabel.setpixmap(pm)

App = QApplication(sys.argv)
window = Window()
sys.exit(App.exec())

我可以更好地实现它吗?当我缩小得太多时,它会写

Qpixmap::scaled: pixmap is a null pixmap

我无法放大

当我在放大和缩小之间切换时,图像的质量 越来越糟。

我从here获取了参数。他们还好吗?

解决方法

您不必使用QLabel + QScrollArea来执行许多任务(例如缩放),而应使用已经实现了这些功能的QGraphicsView:

from PyQt5 import QtWidgets,QtGui,QtCore


class ImageViewer(QtWidgets.QGraphicsView):
    factor = 2.0

    def __init__(self,parent=None):
        super().__init__(parent)
        self.setRenderHints(
            QtGui.QPainter.Antialiasing | QtGui.QPainter.SmoothPixmapTransform
        )
        self.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignTop)
        self.setBackgroundRole(QtGui.QPalette.Dark)

        scene = QtWidgets.QGraphicsScene()
        self.setScene(scene)

        self._pixmap_item = QtWidgets.QGraphicsPixmapItem()
        scene.addItem(self._pixmap_item)

    def load_image(self,fileName):
        pixmap = QtGui.QPixmap(fileName)
        if pixmap.isNull():
            return False
        self._pixmap_item.setPixmap(pixmap)
        return True

    def zoomIn(self):
        self.zoom(self.factor)

    def zoomOut(self):
        self.zoom(1 / self.factor)

    def zoom(self,f):
        self.scale(f,f)

    def resetZoom(self):
        self.resetTransform()

    def fitToWindow(self):
        self.fitInView(self.sceneRect(),QtCore.Qt.KeepAspectRatio)


class MainWindow(QtWidgets.QMainWindow):
    def __init__(self,parent=None):
        super().__init__(parent)

        self.view = ImageViewer()
        self.setCentralWidget(self.view)

        self.createActions()
        self.createMenus()

        self.resize(640,480)

    def open(self):
        image_formats = " ".join(
            [
                "*." + image_format.data().decode()
                for image_format in QtGui.QImageReader.supportedImageFormats()
            ]
        )
        

        fileName,_ = QtWidgets.QFileDialog.getOpenFileName(
            self,self.tr("Open Image"),QtCore.QDir.currentPath(),self.tr("Image Files({})".format(image_formats)),)
        if fileName:
            is_loaded = self.view.load_image(fileName)
            self.fitToWindowAct.setEnabled(is_loaded)
            self.updateActions()

    def fitToWindow(self):
        if self.fitToWindowAct.isChecked():
            self.view.fitToWindow()
        else:
            self.view.resetZoom()
        self.updateActions()

    def about(self):
        QtWidgets.QMessageBox.about(
            self,"ImageViewer",)

    def createActions(self):
        self.openAct = QtWidgets.QAction(
            "&Open...",self,shortcut="Ctrl+O",triggered=self.open
        )
        self.exitAct = QtWidgets.QAction(
            "E&xit",shortcut="Ctrl+Q",triggered=self.close
        )
        self.zoomInAct = QtWidgets.QAction(
            self.tr("Zoom &In (25%)"),shortcut="Ctrl++",enabled=False,triggered=self.view.zoomIn,)
        self.zoomOutAct = QtWidgets.QAction(
            self.tr("Zoom &Out (25%)"),shortcut="Ctrl+-",triggered=self.view.zoomOut,)
        self.normalSizeAct = QtWidgets.QAction(
            self.tr("&Normal Size"),shortcut="Ctrl+S",triggered=self.view.resetZoom,)
        self.fitToWindowAct = QtWidgets.QAction(
            self.tr("&Fit to Window"),checkable=True,shortcut="Ctrl+F",triggered=self.fitToWindow,)
        self.aboutAct = QtWidgets.QAction(self.tr("&About"),triggered=self.about)
        self.aboutQtAct = QtWidgets.QAction(
            self.tr("About &Qt"),triggered=QtWidgets.QApplication.aboutQt
        )

    def createMenus(self):
        self.fileMenu = QtWidgets.QMenu(self.tr("&File"),self)
        self.fileMenu.addAction(self.openAct)
        self.fileMenu.addSeparator()
        self.fileMenu.addAction(self.exitAct)

        self.viewMenu = QtWidgets.QMenu(self.tr("&View"),self)
        self.viewMenu.addAction(self.zoomInAct)
        self.viewMenu.addAction(self.zoomOutAct)
        self.viewMenu.addAction(self.normalSizeAct)
        self.viewMenu.addSeparator()
        self.viewMenu.addAction(self.fitToWindowAct)

        self.helpMenu = QtWidgets.QMenu(self.tr("&Help"),self)
        self.helpMenu.addAction(self.aboutAct)
        self.helpMenu.addAction(self.aboutQtAct)

        self.menuBar().addMenu(self.fileMenu)
        self.menuBar().addMenu(self.viewMenu)
        self.menuBar().addMenu(self.helpMenu)

    def updateActions(self):
        self.zoomInAct.setEnabled(not self.fitToWindowAct.isChecked())
        self.zoomOutAct.setEnabled(not self.fitToWindowAct.isChecked())
        self.normalSizeAct.setEnabled(not self.fitToWindowAct.isChecked())


if __name__ == "__main__":
    import sys

    app = QtWidgets.QApplication(sys.argv)
    w = MainWindow()
    w.show()
    sys.exit(app.exec_())

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。