Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Image scaling quality with a QGraphicsPixmapItem in a QGraphicsScene.



  • Is there a way to tell the viewer (QGraphicsView), the scene (QGraphicsScene) or the object itself (QGraphicsPixmapItem) to use a better scaling algorithm when zooming in and out?

    I'm (pre) viewing images on a QGraphicsView. These are standard DSLR size images (20 to 30 M Pixels). The mechanics of it all work fine. Scale to fit, zooming in and out, panning, etc. My issue is that when the image is reduced, the resampling quality is really poor. If I have the view next to Photoshop (same image), there is a substantial difference in quality when the image is zoomed in (as in, small enough to fit a given window).

    If there is no option to change the scaling algorithm, how would I go about scaling it myself using the OS provided accelerators or other tools such as Intel IPP?

    P.S. I've tried all flags I could find (such as QGraphicsPixmapItem::setTransformationMode(Qt::SmoothTransformation), QGraphicsView::setRenderHints(QPainter::SmoothPixmapTransform), etc.) and none of them makes any difference.

    Thanks in advance,

    g



  • Hi,
    you can use the SmoothPixmapTransform as in the following example where I want to get good scaling of QImage colorImage. You may need to define a QTransform imageTransform to do the actual scaling, though:

    void MyGraphicsView::drawBackground(QPainter *painter, const QRectF &)
    {
    	painter->save();
    	painter->setTransform(imageTransform,true);
    	painter->setRenderHint(QPainter::SmoothPixmapTransform,true);
    	painter->drawImage(QPoint(),colorImage);
    	painter->restore();
    }
    

    drawBackground is a virtual function that draws behind (in the background of) the graphics items.



  • @m.sue Thanks for taking the time to answer. It seems I have quite a bit to dig through before I can make sense of it all. Using your code above (with the exception of You may need to define a QTransform imageTransform to do the actual scaling), the results are identical. High frequency noise in the image gets grossly exaggerated when reduced in size to fit a window.

    What do you mean by define my own QTransform? Reimplement a derived class? Is that the class that does the scaling? Looking through its header file, it doesn't seem it virtualizes any of its methods.

    I'm beginning to wonder if it wouldn't be easier to simply give up on the whole QGraphicsView and just do all the work within a QWidget based class written from scratch. It's hard to imagine QGraphicsView cannot be used for high-end image viewing though...



  • The following transform should scale the image by a factor of 1.5.

    QTransform imageTransform;
    imageTransform.scale(1.5,1.5);
    

    But you may be right, as I never used it to reduced the size of an image, so far. So if that does not work well you'll have to wait for someone else to find a better answer.
    -Michael.



  • @m.sue Got it. So QTransform only defines the transform. At first I was under the impression it did the actual subsampling (where I could replace the code and do my own, real subsampling). In that case, no. QPainter::SmoothPixmapTransform has no effect and produces an image with lots of artifacts. I may elevate this question.

    Thanks!


Log in to reply