Bad Svg in QGraphicsView [Qt 5.5]



  • Hello everyone
    I've a problem with some svg icons and retina monitor..
    they looks perfect when are scaled at 100% but if are under 100% they looks really bad
    here's my code

    #include <QApplication>
    #include <QDebug>
    #include <QWidget>
    #include <QGraphicsView>
    #include <QGraphicsSvgItem>
    #include <QSvgRenderer>
    
    int main(int argc, char **argv)
    {
        QApplication app(argc, argv);
    
        QGraphicsScene scene;
        QGraphicsView view(&scene);
    
        QString pic(argv[1]);
        QSvgRenderer renderer(pic);
    
        int w = 58;
        int h = 58;
        int hdpi = 2;
        QImage image(w*hdpi, h*hdpi, QImage::Format_ARGB32);
        QPainter painter(&image);
        renderer.render(&painter);
    
        QGraphicsPixmapItem pix( QPixmap::fromImage(image));
        //pix.setScale(1.0/hdpi); // 100%
        pix.setScale(0.4/hdpi);
        scene.addItem(&pix);
    
        view.show();
        return app.exec();
    }
    
    

    here the result
    link text

    and at 100%
    link text

    are there something wrong in my code ?
    Help me please! ;-)

    Tnks.
    GG


  • Qt Champions 2016

    hi
    have you tried with
    painter.setRenderHint(QPainter::Antialiasing);
    or
    painter.setRenderHint(QPainter::HighQualityAntialiasing);
    to see if u can get it to smooth it ?


  • Qt Champions 2016

    @GGAllin
    You're scaling a raster image, so don't do that. Instead provide a smaller image for the QSvgRenderer to render onto. For example, what's wrong with this?

        QImage image(0.4 * w, 0.4* h, QImage::Format_ARGB32);
        QPainter painter(&image);
        renderer.render(&painter);
    
        QGraphicsPixmapItem pix( QPixmap::fromImage(image));
        scene.addItem(&pix);
    

    The idea is that the last thing you do is render the vector data to raster, so you can actually keep the quality.



  • @mrjj

    @mrjj said:

    hi
    have you tried with
    painter.setRenderHint(QPainter::Antialiasing);
    or
    painter.setRenderHint(QPainter::HighQualityAntialiasing);
    to see if u can get it to smooth it ?

    @kshegunov said:

    @GGAllin
    You're scaling a raster image, so don't do that. Instead provide a smaller image for the QSvgRenderer to render onto. For example, what's wrong with this?

        QImage image(0.4 * w, 0.4* h, QImage::Format_ARGB32);
        QPainter painter(&image);
        renderer.render(&painter);
    
        QGraphicsPixmapItem pix( QPixmap::fromImage(image));
        scene.addItem(&pix);
    

    The idea is that the last thing you do is render the vector data to raster, so you can actually keep the quality.

    @mrjj said:

    hi
    have you tried with
    painter.setRenderHint(QPainter::Antialiasing);
    or
    painter.setRenderHint(QPainter::HighQualityAntialiasing);
    to see if u can get it to smooth it ?

    Nothing change with QPainter::HighQualityAntialiasing or QPainter::Antialiasing


  • Qt Champions 2016

    ok.
    good to know.
    Was just a shot.

    so @kshegunov way should do it :)



  • Yeah!```
    QImage image(0.4 * w, 0.4* h, QImage::Format_ARGB32);
    QPainter painter(&image);
    renderer.render(&painter);

    QGraphicsPixmapItem pix( QPixmap::fromImage(image));
    scene.addItem(&pix);
    
    
    works perfect!
    Many thanks to all!!


  • better result using fill(Qt::Transparent)

        int w = svgSize.width();
        int h = svgSize.height();
        int hdpi = docView->devicePixelRatio() <2 ? 1: 2;
        QSvgRenderer renderer("icon.svg");
        QImage image(scaleF*w*hdpi,scaleF* h*hdpi, QImage::Format_ARGB32);
        image.fill(Qt::TransparentMode);
        QPainter painter(&image);
        painter.setRenderHint(QPainter::HighQualityAntialiasing);
        renderer.render(&painter);
        QGraphicsPixmapItem* pix =new QGraphicsPixmapItem(QPixmap::fromImage(image));
        pix->setScale(1.0/hdpi);
    

  • Qt Champions 2016

    @GGAllin
    Forgive my ignorance, but how is this:

    QImage image(scaleF * w * hdpi, scaleF * h * hdpi, QImage::Format_ARGB32);
    QGraphicsPixmapItem* pix = new QGraphicsPixmapItem(QPixmap::fromImage(image));
    pix->setScale(1.0 / hdpi);
    

    different from this:

    QImage image(scaleF * w, scaleF * h, QImage::Format_ARGB32);
    QGraphicsPixmapItem* pix = new QGraphicsPixmapItem(QPixmap::fromImage(image));
    

    The whole point of using vector graphics is not to scale raster images, but to render directly to the correct sizes. isn't it? So why do you insist on rendering a larger image and then scaling it down?


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.