Wie Qimage mit QPainter::drawImage() in höchster Qualität zeichnen?



  • Hallo,

    ich möchte in höchster Grafikqualität ein QImage mit fester Größe auf Bildschirmfenstergröße skalieren:

    void Paint::paintEvent(QPaintEvent *)
    {
        QImage image(1600, 1200, QImage::Format_ARGB32_Premultiplied);
        QPainter pImage(&image);
        pImage.initFrom(this);
        pImage.setRenderHint(QPainter::Antialiasing, true);
    
        pImage.setPen(QPen(Qt::black, 20));
        pImage.drawRect(QRect(300,200,800,500));
    
        pImage.setFont(QFont("Arial", 20, QFont::Bold));
        pImage.drawText(QPoint(400, 400), "Dies ist ein QImage Test");
    
        pImage.end();
    
        QPainter p(this);
        QSize screenSize = size();
        p.drawImage(QRect(0, 0, screenSize.width(), screenSize.width()), image);
    };
    

    Dieses Codebeispiel funktioniert, jedoch wird QImage dabei leicht horizontal gestaucht angezeigt. Und die Render Qualität von drawText() läßt auch zu wünschen übrig.

    Wie kann ein QImage in höchster Qualität angezeigt werden?



  • Mehr wüsste ich jetzt (spontan) auch nicht.



  • Hallo Mechanics,

    im Grunde geht es darum, eine Grafik fester Größe in höchst möglicher Qualität auf Bildschirmgröße zu skalieren.

    Bisher hatte ich das über QPainter::scale() gemacht. Jedoch ist die Darstellungsqualität am Bildschirm damit sehr schlecht:

    void CPaint::paintEvent(QPaintEvent *)
    {
        QPainter P(this);
    
        P.setRenderHints(QPainter::Antialiasing |
                         QPainter::SmoothPixmapTransform |
                         QPainter::TextAntialiasing, true);
    
        int side = qMin(width(), height());
        P.scale(side / 10000.0, side / 10000.0);
    
        CZeichnung Z();
        Z.Zeichne();
    };
    

    In der Qt Dokumetation habe ich dann gelesen, dass das an der Funktionsweise von scale() liegt. Falls der Skalingswert unter 0.5 liegt, soll das Rendering schlecht werden. Bei mir liegt er aber bei ca. 0.05:

    https://bugreports.qt.io/browse/QTBUG-30682

    Für eine höhere Skalierungsqualität soll der Umweg über QImage oder QPixImage gegangen werden. Aber wie oben zu sehen, komme ich da auch nicht viel weiter.

    Eigentlich ist Skalierung auf Bildschirmgröße doch ein gängiges Problem.

    Welcher Lösungsansatz ist dafür am besten geeignet?



  • Zur Rendering Qalität von QImage habe ich jetzt noch eine Lösung im Netz gefunden:
    http://stackoverflow.com/questions/21857178/qimage-dithering-quality

    void Paint::paintEvent(QPaintEvent *)
    {
        QImage Image(1600, 1200, QImage::Format_ARGB32_Premultiplied);
        QPainter pImage(&Image);
        pImage.initFrom(this);
        pImage.setRenderHint(QPainter::Antialiasing, true);
    
        pImage.setPen(QPen(Qt::black, 20));
        pImage.drawRect(QRect(300,200,800,500));
    
        pImage.setFont(QFont("Arial", 20, QFont::Bold));
        pImage.drawText(QPoint(400, 400), "Dies ist ein QImage Test");
    
        pImage.end();
    
        QPainter p(this);
        QImage scaledImage = Image.scaled(size(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
        QSize screenSize = size();
        p.drawImage(QRectF(0, 0, screenSize.width(), screenSize.width()*1200/1600), scaledImage, scaledImage.rect());
    };
    

    Leider hat das auch nicht wirkliche Verbesserung gebracht. 😞



  • Naja, viel mehr Optionen als Antialiasing und SmoothPixmapTransform gibts da glaub ich auch nicht. Du kannst vielleicht schauen, ob du andere Bibliotheken/Algorithmen findest, die in deinem Fall besser funktionieren.



  • Öhm, ja es ist doch kein Wunder wenn sich das Bild verzerrt. Du skalierst auf ein hart codiertes Seitenverhältnis ohne Rücksicht auf das des Bildes oder des Bildschirmes.

    Hast du dir schon mal Qt::KeepAspectRatio angesehen? Du gibst ja bewusst IgnoreAspectRatio an...


Anmelden zum Antworten