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