PDA

View Full Version : How to apply QPainter::SmoothPixmapTransform to QGracphicsView?



egaudrain
9th November 2011, 14:57
Hi,

I'm using PyQt4 (4.8.4, based on Qt 4.7.2). I want to display pixmaps on the screen every time the user presses a key. So far so good.
But I also want to scale and rotate the images. Then bad things happen. I use the GraphicsScene framework and the setRotation item method to rotate the pixmap. This much works except that I don't seem to be able get any smoothing to work.

Here's my code:


class MainWindow(QWidget):
def __init__(self):
QMainWindow.__init__(self, None) #, Qt.FramelessWindowHint)

self.setWindowState(Qt.WindowFullScreen)

self.vL = QVBoxLayout()
self.setLayout(self.vL)

self.scene = QGraphicsScene()
self.view = QGraphicsView(self)

#~ self.view.setRenderHint(QPainter.SmoothPixmapTrans form, False)
self.view.setScene(self.scene)

self.view.setHorizontalScrollBarPolicy(Qt.ScrollBa rAlwaysOff)
self.view.setVerticalScrollBarPolicy(Qt.ScrollBarA lwaysOff)
self.vL.addWidget(self.view)

self.view.setRenderHints(QPainter.SmoothPixmapTran sform | QPainter.Antialiasing)
self.view.setSceneRect(0, 0, self.width(), self.height())

self.img_list = glob('img/*.jpg')
self.img_list.extend(glob('img/*.png'))


def keyPressEvent(self, event):
event.accept()
self.disp_image(self.img_list[random.choice(range(len(self.img_list)))])

def disp_image(self, file, position=None):

pxmap = QPixmap(file)
i = self.scene.addPixmap(pxmap)
i.setTransformOriginPoint(pxmap.width()/2., pxmap.height()/2.)
i.setRotation(10)
i.setPos((.8*random.random()+.1)*self.width()-pxmap.width()/2., (.8*random.random()+.1)*self.height()-pxmap.height()/2.)

self.view.show()


Whatever I do, the QPainter.SmoothPixmapTransform seems to be ineffective (see the attachements: one is Tux rotated using Qt, the next is Tux rotated using XnView).
I've tried many many things: using an OpenGL viewport instead of the default raster one; declaring the hints before setting the scene; setting the hints after each item is added to the scene; even tried a method propose elsewhere where the view is retrieved from the item itself; also view.show() doesn't seem to be required or doing anything.

I've spent the last 2 days googling this but couldn't find a clue. Someone seems to have had the same problem in 2007 but got no response...

Any clues?
Ah, I've tried that on WinXP only by the way.

Thanks a lot for any hint!
-Etienne

egaudrain
11th November 2011, 10:10
Gosh...
Is it an extraordinarily tricky question, or is it the dumbest question ever asked, so dumb that it doesn't require answers ?

I wondered if that was a license issue... there is a slightly atypical copyright statement in the QImage page... but bilinear algorithms are nothing secret or protected (although a specific optimized implementation might be). Anyway, I've ruled that out since everything's fine if I transform the QImage rather than the QGraphicsPixmapItem. This is just pretty slow (QImage, transform, convert to QPixmap, insert in scene).

I also wanted to add that, yeah, render hints are just hints, they are not necessarily satisfied by the painting device. Fair enough. But that would be good to know when it can be expected them to be.

In the end I've given up using pixmaps, and am only using SVG files. But that would have been nice to be able to do both, so if anyone has any clue, I'm still all ears wide open.

Cheers.

matejliszka
17th June 2012, 17:43
Hi Etienne

Hopefully you found the solution meanwhile. If not, and for the others who come to this thread, I found a solution to this problem at least on my platform (Qt 4.6.3 for Symbian). It is quite simple (it just requires to know the classes you are using or to have good luck when googling :) ).

Before you call setRotation, call setTransformationMode(Qt::SmoothTransformation) on the bitmap.

Calling setRenderHints on the view is even not necessary for that smooth transformation to work.

Matej