TP a écrit :
> I'm using Windows XP, Python 2.6.4, and PyQt 4.7.1.
>
> While trying out the example
> C:\Python26\Lib\site-packages\PyQt4\examples\widgets\imageviewer.pyw,
> I notice that the more I zoom into an 1553x2653 B&W PNG image, the
> longer it takes to display. This becomes unacceptably long (on the
> order of a few seconds) at the not so high 3x zoom factor.
>
> Intuitively, I would have thought it would be *faster* since the more
> I zoom in the fewer image pixels need to be displayed. I think what's
> happening is the entire QLabel widget is getting enlarged then
> cropped, rather than just displaying a sub-portion of the image:
>
>     def scaleImage(self, factor):
>         self.scaleFactor *= factor
>         self.imageLabel.resize(self.scaleFactor *
> self.imageLabel.pixmap().size())
>
> I want to create an app to help people explore various image
> processing operations. Fast & flexible image display is essential.
>
> Some features I like to have:
>
> * Zoom In/Out quickly. I can see zooming *out* being slower since more
>   image pixels would be involved. Once past the 1x zoom-in factor, I'd
>   rather have the pixels as raw as possible to avoid blurring edges
>   like the Image Viewer example currently does.
>
> * Compare transformations by having multiple views of images that are
>   synchronized as to pan position and zoom factor. Dragging the mouse
>   in any of the views should pan all the views.
>
> * Multi-screen support.
>
> I started off by modifying the PyQt4 Image Viewer example, but now I'm
> having second thoughts. Should I really be basing my Image Viewer on a
> QLabel?
>
> Should I instead be using a QGraphicsView (even though I'll probably
> only have a single image, not lots of 2D objects)?
>
> Maybe I should use a QGLWidget (I'd rather not).
>
> Or perhaps I have to write my own custom widget and draw using a
> QPainter object?
>
> Any tips or pointers to other PyQt-based Image Viewers would be
> appreciated.
> _______________________________________________
> PyQt mailing list    PyQt@riverbankcomputing.com
> http://www.riverbankcomputing.com/mailman/listinfo/pyqt
>
>   
See attachement, it's an images viewer + zoom with QGraphicScene.

Before use, change the line 63

Vincent
#!/usr/bin/env python
# -*- coding: utf-8 -*-

# Example of an image viewer with zoom
#
# Created: Thu Feb 25 19:54:49 2010
#      by: PyQt4 UI code generator 4.4.4
#
# Author: Vincent Vande Vyvre <v...@swing.be>
#
# Note: before use, change the line 63

import os
import time
import glob

from PyQt4 import QtCore, QtGui

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.resize(900, 600)
        self.centralwidget = QtGui.QWidget(MainWindow)
        self.gridLayout = QtGui.QGridLayout(self.centralwidget)
        self.verticalLayout = QtGui.QVBoxLayout()
        self.scene = QtGui.QGraphicsScene()
        self.view = QtGui.QGraphicsView(self.scene)
        self.verticalLayout.addWidget(self.view)
        self.horizontalLayout = QtGui.QHBoxLayout()
        spacerItem = QtGui.QSpacerItem(150, 20, QtGui.QSizePolicy.Expanding,
                                        QtGui.QSizePolicy.Minimum)
        self.horizontalLayout.addItem(spacerItem)
        self.toolButton_3 = QtGui.QToolButton(self.centralwidget)
        self.toolButton_3.setIconSize(QtCore.QSize(48, 24))
        self.toolButton_3.setText("Previous")
        self.horizontalLayout.addWidget(self.toolButton_3)
        self.toolButton_4 = QtGui.QToolButton(self.centralwidget)
        self.toolButton_4.setIconSize(QtCore.QSize(48, 24))
        self.toolButton_4.setText("Next")
        self.horizontalLayout.addWidget(self.toolButton_4)
        spacerItem1 = QtGui.QSpacerItem(100, 20, QtGui.QSizePolicy.Expanding,
                                        QtGui.QSizePolicy.Minimum)
        self.horizontalLayout.addItem(spacerItem1)
        self.toolButton_6 = QtGui.QToolButton(self.centralwidget)
        self.toolButton_6.setText("Quit")
        self.horizontalLayout.addWidget(self.toolButton_6)
        self.verticalLayout.addLayout(self.horizontalLayout)
        self.gridLayout.addLayout(self.verticalLayout, 0, 0, 1, 1)
        MainWindow.setCentralWidget(self.centralwidget)
        MainWindow.setWindowTitle("speedyView")
        MainWindow.show()
        QtCore.QCoreApplication.processEvents()

        QtCore.QObject.connect(ui.toolButton_3, QtCore.SIGNAL("clicked()"), self.prec)
        QtCore.QObject.connect(ui.toolButton_4, QtCore.SIGNAL("clicked()"), self.next)
        QtCore.QObject.connect(ui.toolButton_6, QtCore.SIGNAL("clicked()"), exit)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

        self.centralwidget.wheelEvent = self.wheel_event

        self.set_view()

    def set_view(self):
        in_folder = "/folder/with/images/"
        chain = in_folder + "/*"
        self.images = glob.glob(chain)
        self.images.sort(cmp=lambda x, y: cmp(x.lower(), y.lower()))
        self.zoom_step = 0.04
        self.w_vsize = self.view.size().width()
        self.h_vsize = self.view.size().height()
        if self.w_vsize <= self.h_vsize:
            self.max_vsize = self.w_vsize
        else:
            self.max_vsize = self.h_vsize
        self.l_pix = ["", "", ""]

        self.i_pointer = 0
        self.p_pointer = 0
        self.load_current()
        self.p_pointer = 1
        self.load_next()
        self.p_pointer = 2
        self.load_prec()
        self.p_pointer = 0

    def next(self):
        self.i_pointer += 1
        if self.i_pointer == len(self.images):
            self.i_pointer = 0
        self.p_view = self.c_view
        self.c_view = self.n_view
        self.view_current()
        if self.p_pointer == 0:
            self.p_pointer = 2
            self.load_next()
            self.p_pointer = 1
        elif self.p_pointer == 1:
            self.p_pointer = 0
            self.load_next()
            self.p_pointer = 2
        else:
            self.p_pointer = 1
            self.load_next()
            self.p_pointer = 0

    def prec(self):
        self.i_pointer -= 1
        if self.i_pointer <= 0:
            self.i_pointer = len(self.images)-1
        self.n_view = self.c_view
        self.c_view = self.p_view
        self.view_current()
        if self.p_pointer == 0:
            self.p_pointer = 1
            self.load_prec()
            self.p_pointer = 2
        elif self.p_pointer == 1:
            self.p_pointer = 2
            self.load_prec()
            self.p_pointer = 0
        else:
            self.p_pointer = 0
            self.load_prec()
            self.p_pointer = 1

       
    def view_current(self):
        size_img = self.c_view.size()
        wth, hgt = QtCore.QSize.width(size_img), QtCore.QSize.height(size_img)
        self.scene.clear()
        self.scene.setSceneRect(0, 0, wth, hgt)
        self.scene.addPixmap(self.c_view)
        QtCore.QCoreApplication.processEvents()

    def load_current(self):
        self.l_pix[self.p_pointer] = QtGui.QPixmap(self.images[self.i_pointer])
        self.c_view = self.l_pix[self.p_pointer].scaled(self.max_vsize, self.max_vsize, 
                                            QtCore.Qt.KeepAspectRatio, 
                                            QtCore.Qt.FastTransformation)
        #change the previous line with QtCore.Qt.SmoothTransformation eventually
        self.view_current()

    def load_next(self):
        if self.i_pointer == len(self.images)-1:
            p = 0
        else:
            p = self.i_pointer + 1
        self.l_pix[self.p_pointer] = QtGui.QPixmap(self.images[p])
        self.n_view = self.l_pix[self.p_pointer].scaled(self.max_vsize, 
                                            self.max_vsize, 
                                            QtCore.Qt.KeepAspectRatio, 
                                            QtCore.Qt.FastTransformation)

    def load_prec(self):
        if self.i_pointer == 0:
            p = len(self.images)-1
        else:
            p = self.i_pointer - 1
        self.l_pix[self.p_pointer] = QtGui.QPixmap(self.images[p])
        self.p_view = self.l_pix[self.p_pointer].scaled(self.max_vsize, 
                                            self.max_vsize, 
                                            QtCore.Qt.KeepAspectRatio, 
                                            QtCore.Qt.FastTransformation)

    def wheel_event (self, event):
        numDegrees = event.delta() / 8
        numSteps = numDegrees / 15.0
        self.zoom(numSteps)
        event.accept()

    def zoom(self, step):
        self.scene.clear()
        w = self.c_view.size().width()
        h = self.c_view.size().height()
        w, h = w * (1 + self.zoom_step*step), h * (1 + self.zoom_step*step)
        self.c_view = self.l_pix[self.p_pointer].scaled(w, h, 
                                            QtCore.Qt.KeepAspectRatio, 
                                            QtCore.Qt.FastTransformation)
        self.view_current()

if __name__ == "__main__":
    import sys
    app = QtGui.QApplication(sys.argv)
    MainWindow = QtGui.QMainWindow()
    ui = Ui_MainWindow()
    ui.setupUi(MainWindow)
    MainWindow.show()
    sys.exit(app.exec_())

_______________________________________________
PyQt mailing list    PyQt@riverbankcomputing.com
http://www.riverbankcomputing.com/mailman/listinfo/pyqt

Reply via email to