Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Image gets de-pixalated or distorted (unclear) when we change the desktop display scale to 125%
QtWS25 Last Chance

Image gets de-pixalated or distorted (unclear) when we change the desktop display scale to 125%

Scheduled Pinned Locked Moved Unsolved General and Desktop
17 Posts 5 Posters 645 Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • W Offline
    W Offline
    wasimIM
    wrote on last edited by
    #1

    Hi all, hope you are doing good.

    I am using QT for one of my desktop application. I am trying to show a pdf inside a QT widget QPainter.
    The pdf looks just fine when I launch the application. But, when I am changing the display scale to 125% resolution.
    Then the drawing in the pdf gets distorted, or unclear. Changing back the scale to 100% makes it clear again.
    But, it should not happen in the first place.

    To demonstrate that, I have developed a sample application and used an image to show inside the qpainter.
    Same issue occurs.
    Clear image at 100% scale
    s1.png
    unclear/distorted image at 125% scale.
    s2.png

    Currently I am using QT 6.8.1. the issue doesn't reproduce on QT 5.14.2 version and below.

    This is a blocker for me. Can someone please help me with it.

    Below is the code part.

    main.cpp ```
    #include "QtPainterDemo681.h"
    #include <QtWidgets/QApplication>

    int main(int argc, char *argv[])
    {
    QApplication a(argc, argv);
    QtPainterDemo681 w;
    w.resize(1400, 700);
    w.show();
    return a.exec();
    }

    
    QtPainterDemo681.h
    

    #pragma once

    #include <QtWidgets/QMainWindow>
    #include "ui_QtPainterDemo681.h"
    #include <QApplication>
    #include <QWidget>
    #include <QPainter>
    #include <QImage>
    #include <QMouseEvent>
    #include <QDebug>

    class QtPainterDemo681 : public QMainWindow
    {
    Q_OBJECT

    public:
    QtPainterDemo681(QWidget *parent = nullptr);
    ~QtPainterDemo681();

    virtual void paintEvent(QPaintEvent* eventP);
    

    private:
    Ui::QtPainterDemo681Class ui;
    };

    QtPainterDemo681.cpp 
    

    #include "QtPainterDemo681.h"

    QtPainterDemo681::QtPainterDemo681(QWidget *parent)
    : QMainWindow(parent)
    {
    ui.setupUi(this);
    }

    QtPainterDemo681::~QtPainterDemo681()
    {}

    void QtPainterDemo681::paintEvent(QPaintEvent* eventP)
    {
    QPainter painter(this);

    QImage image("../../clearImag.jpg");
    if (image.isNull()) {
        qDebug() << "Failed to load image.";
        return;
    }
    painter.drawImage(0, 0, image);
    

    }

    Pl45m4P 1 Reply Last reply
    0
    • W wasimIM

      Hi all, hope you are doing good.

      I am using QT for one of my desktop application. I am trying to show a pdf inside a QT widget QPainter.
      The pdf looks just fine when I launch the application. But, when I am changing the display scale to 125% resolution.
      Then the drawing in the pdf gets distorted, or unclear. Changing back the scale to 100% makes it clear again.
      But, it should not happen in the first place.

      To demonstrate that, I have developed a sample application and used an image to show inside the qpainter.
      Same issue occurs.
      Clear image at 100% scale
      s1.png
      unclear/distorted image at 125% scale.
      s2.png

      Currently I am using QT 6.8.1. the issue doesn't reproduce on QT 5.14.2 version and below.

      This is a blocker for me. Can someone please help me with it.

      Below is the code part.

      main.cpp ```
      #include "QtPainterDemo681.h"
      #include <QtWidgets/QApplication>

      int main(int argc, char *argv[])
      {
      QApplication a(argc, argv);
      QtPainterDemo681 w;
      w.resize(1400, 700);
      w.show();
      return a.exec();
      }

      
      QtPainterDemo681.h
      

      #pragma once

      #include <QtWidgets/QMainWindow>
      #include "ui_QtPainterDemo681.h"
      #include <QApplication>
      #include <QWidget>
      #include <QPainter>
      #include <QImage>
      #include <QMouseEvent>
      #include <QDebug>

      class QtPainterDemo681 : public QMainWindow
      {
      Q_OBJECT

      public:
      QtPainterDemo681(QWidget *parent = nullptr);
      ~QtPainterDemo681();

      virtual void paintEvent(QPaintEvent* eventP);
      

      private:
      Ui::QtPainterDemo681Class ui;
      };

      QtPainterDemo681.cpp 
      

      #include "QtPainterDemo681.h"

      QtPainterDemo681::QtPainterDemo681(QWidget *parent)
      : QMainWindow(parent)
      {
      ui.setupUi(this);
      }

      QtPainterDemo681::~QtPainterDemo681()
      {}

      void QtPainterDemo681::paintEvent(QPaintEvent* eventP)
      {
      QPainter painter(this);

      QImage image("../../clearImag.jpg");
      if (image.isNull()) {
          qDebug() << "Failed to load image.";
          return;
      }
      painter.drawImage(0, 0, image);
      

      }

      Pl45m4P Offline
      Pl45m4P Offline
      Pl45m4
      wrote on last edited by
      #2

      @wasimIM said in Image gets de-pixalated or distorted (unclear) when we change the desktop display scale to 125%:

      The pdf looks just fine when I launch the application

      You say PDF, but the code loads a JPEG?!

      And this exact code does not distort the image on old Qt versions but it does on recent ones?!


      If debugging is the process of removing software bugs, then programming must be the process of putting them in.

      ~E. W. Dijkstra

      1 Reply Last reply
      0
      • W Offline
        W Offline
        wasimIM
        wrote on last edited by
        #3

        @Pl45m4 PDF is used in my real application, the code is of a sample application. As I said. But, issue occured is same.
        Yes, in older versions it works fine.

        1 Reply Last reply
        0
        • Christian EhrlicherC Online
          Christian EhrlicherC Online
          Christian Ehrlicher
          Lifetime Qt Champion
          wrote on last edited by
          #4

          When you display an image with 1000x1000 on a screen with a dpr=1,25 and a size of 1000x1000 then the image needs 1250pixels so it's scaled up. This is what you're seeing. So you should either create a pixmap with 1250x1250 pixels or use 1000/1.25=800x800 as size.

          Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
          Visit the Qt Academy at https://academy.qt.io/catalog

          W 1 Reply Last reply
          2
          • W Offline
            W Offline
            wasimIM
            wrote on last edited by
            #5

            @Christian-Ehrlicher But why does the same code work for QT 5.14.2 version? This is regressed after QT 5.14.2.

            1 Reply Last reply
            0
            • Christian EhrlicherC Online
              Christian EhrlicherC Online
              Christian Ehrlicher
              Lifetime Qt Champion
              wrote on last edited by
              #6

              I don't know but would guess it's because of the lack of proper high-dpi handling in Qt5.

              Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
              Visit the Qt Academy at https://academy.qt.io/catalog

              1 Reply Last reply
              0
              • Christian EhrlicherC Christian Ehrlicher

                When you display an image with 1000x1000 on a screen with a dpr=1,25 and a size of 1000x1000 then the image needs 1250pixels so it's scaled up. This is what you're seeing. So you should either create a pixmap with 1250x1250 pixels or use 1000/1.25=800x800 as size.

                W Offline
                W Offline
                wasimIM
                wrote on last edited by
                #7

                @Christian-Ehrlicher I didn't get this completely, I tried creating pixmap with 1250 x 1250. with code as below , but same issue. And 800x800 size of what?

                QPixmap pixmap(1250, 1250);
                if (!pixmap.load("D:/temp/clearImag.jpg")) { // Load the image into QPixmap
                    qWarning("Failed to load image");
                }
                
                1 Reply Last reply
                0
                • Christian EhrlicherC Online
                  Christian EhrlicherC Online
                  Christian Ehrlicher
                  Lifetime Qt Champion
                  wrote on last edited by
                  #8

                  Since the png or jpeg has a size, this is used when you create a QPixmap from it... I don't understand what you try to achieve here.
                  When you display an image with 1000x1000 on a screen with a dpr of 1.25 the resulting size of the image on the screen is 800x800 pixels because 800*1.25=1000

                  Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                  Visit the Qt Academy at https://academy.qt.io/catalog

                  1 Reply Last reply
                  0
                  • W Offline
                    W Offline
                    wasimIM
                    wrote on last edited by
                    #9

                    @Christian-Ehrlicher I just want to display a clear image. It should not be unclear with changing of the scaling.

                    1 Reply Last reply
                    0
                    • Christian EhrlicherC Online
                      Christian EhrlicherC Online
                      Christian Ehrlicher
                      Lifetime Qt Champion
                      wrote on last edited by
                      #10

                      Since a pixel based image can not be scaled without artificacts I don't see any solution.

                      Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                      Visit the Qt Academy at https://academy.qt.io/catalog

                      1 Reply Last reply
                      0
                      • GrecKoG Offline
                        GrecKoG Offline
                        GrecKo
                        Qt Champions 2018
                        wrote on last edited by
                        #11

                        I would try calling QPixmap/QImage::setDevicePixelRatio with the same device pixel ratio as the underlying QScreen.

                        Christian EhrlicherC 1 Reply Last reply
                        2
                        • I Offline
                          I Offline
                          IgKh
                          wrote on last edited by
                          #12

                          Exactly what @GrecKo said. In Qt 6, there was an overhaul of how HiDPI displays are handled - now Qt consistently works in Device Independent Pixels (DIPs), which are mapped to physical pixels by the paint engine. This means that anything painted with QPainter calls or otherwise through vector operations always correctly scales without the program needing to do anything, this is not the case for things painted from a pixmap. As experienced by OP, the automatic scaling of bitmaps hurts quality - but it is needed as otherwise the image would be too small.

                          The way to get around it is to tell Qt explicitly what is the scaling ratio that the image is intended to be viewed at using the setDevicePixelRatio. If it is identical to the target drawing surfaces' scaling ratio, Qt will not do any automatic scaling of the image.

                          Do note that indeed if the image is 1000X1000 physical pixels, and the scaling ratio is 1.25 for both the image and the widget - it will take 800x800 DIPs. This means that as the scaling ratio grows, the image will be drawn smaller and smaller. At some point you'll need to switch to an extra high quality version of the original image that has more pixel density, and Qt does have support for that. See https://doc.qt.io/qt-6/qpainter.html#drawing-high-resolution-versions-of-pixmaps-and-images

                          1 Reply Last reply
                          1
                          • GrecKoG GrecKo

                            I would try calling QPixmap/QImage::setDevicePixelRatio with the same device pixel ratio as the underlying QScreen.

                            Christian EhrlicherC Online
                            Christian EhrlicherC Online
                            Christian Ehrlicher
                            Lifetime Qt Champion
                            wrote on last edited by
                            #13

                            @GrecKo said in Image gets de-pixalated or distorted (unclear) when we change the desktop display scale to 125%:

                            I would try calling QPixmap/QImage::setDevicePixelRatio with the same device pixel ratio as the underlying QScreen.

                            How should this help? When he wants to draw an image with 1000x1000px on a screen with 1000x1000 (and this is what he's doing), there are effectively 1250x1250 pixels needed to draw the image so a scaling will occour. The only way to avoid scaling is, as I already wrote, to paint it with 800x800px.

                            Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                            Visit the Qt Academy at https://academy.qt.io/catalog

                            I GrecKoG 2 Replies Last reply
                            0
                            • Christian EhrlicherC Christian Ehrlicher

                              @GrecKo said in Image gets de-pixalated or distorted (unclear) when we change the desktop display scale to 125%:

                              I would try calling QPixmap/QImage::setDevicePixelRatio with the same device pixel ratio as the underlying QScreen.

                              How should this help? When he wants to draw an image with 1000x1000px on a screen with 1000x1000 (and this is what he's doing), there are effectively 1250x1250 pixels needed to draw the image so a scaling will occour. The only way to avoid scaling is, as I already wrote, to paint it with 800x800px.

                              I Offline
                              I Offline
                              IgKh
                              wrote on last edited by IgKh
                              #14

                              @Christian-Ehrlicher

                              Same difference. It is just that:

                              void Whatever::paintEvent(QPaintEvent* e)
                              {
                                  // ...snip...
                                  
                                  image.setDevicePixelRatio(devicePixelRatio());
                                  painter.drawImage(0, 0, image);
                              }
                              

                              Is identical to but often easier to do than:

                              void Whatever::paintEvent(QPaintEvent* e)
                              {
                                  // ...snip...
                                  
                                  painter.drawImage(QRectF(0, 0, image.width() / devicePixelRatio(), image.height() / devicePixelRatio()), image);
                              }
                              

                              Since it can be done once after loading the image, and is an easy way to make sure the image is not scaled. It is true that it makes the image smaller, but it doesn't seem like the OP wanted it to be same size, they just wanted it to not be blurry?

                              Christian EhrlicherC 1 Reply Last reply
                              0
                              • I IgKh

                                @Christian-Ehrlicher

                                Same difference. It is just that:

                                void Whatever::paintEvent(QPaintEvent* e)
                                {
                                    // ...snip...
                                    
                                    image.setDevicePixelRatio(devicePixelRatio());
                                    painter.drawImage(0, 0, image);
                                }
                                

                                Is identical to but often easier to do than:

                                void Whatever::paintEvent(QPaintEvent* e)
                                {
                                    // ...snip...
                                    
                                    painter.drawImage(QRectF(0, 0, image.width() / devicePixelRatio(), image.height() / devicePixelRatio()), image);
                                }
                                

                                Since it can be done once after loading the image, and is an easy way to make sure the image is not scaled. It is true that it makes the image smaller, but it doesn't seem like the OP wanted it to be same size, they just wanted it to not be blurry?

                                Christian EhrlicherC Online
                                Christian EhrlicherC Online
                                Christian Ehrlicher
                                Lifetime Qt Champion
                                wrote on last edited by
                                #15

                                @IgKh said in Image gets de-pixalated or distorted (unclear) when we change the desktop display scale to 125%:

                                ut it doesn't seem like the OP wanted it to be same size, they just wanted it to not be blurry?

                                I don't know, we just get a 'sample application' so ...

                                I am trying to show a pdf inside a QT widget QPainter. The pdf looks just fine when I launch the application.

                                ... we don't know how the pdf is converted to a QImage/QPixmap/whatsoever.
                                I already told them to simply render the pdf image (as I would guess it's done this way e.g. with poppler) in size * dpr instead size but he doesn't care.

                                Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                                Visit the Qt Academy at https://academy.qt.io/catalog

                                1 Reply Last reply
                                0
                                • Christian EhrlicherC Christian Ehrlicher

                                  @GrecKo said in Image gets de-pixalated or distorted (unclear) when we change the desktop display scale to 125%:

                                  I would try calling QPixmap/QImage::setDevicePixelRatio with the same device pixel ratio as the underlying QScreen.

                                  How should this help? When he wants to draw an image with 1000x1000px on a screen with 1000x1000 (and this is what he's doing), there are effectively 1250x1250 pixels needed to draw the image so a scaling will occour. The only way to avoid scaling is, as I already wrote, to paint it with 800x800px.

                                  GrecKoG Offline
                                  GrecKoG Offline
                                  GrecKo
                                  Qt Champions 2018
                                  wrote on last edited by
                                  #16

                                  @Christian-Ehrlicher said in Image gets de-pixalated or distorted (unclear) when we change the desktop display scale to 125%:

                                  The only way to avoid scaling is, as I already wrote, to paint it with 800x800px.

                                  That's what setDevicePixelRatio does.

                                  Christian EhrlicherC 1 Reply Last reply
                                  0
                                  • GrecKoG GrecKo

                                    @Christian-Ehrlicher said in Image gets de-pixalated or distorted (unclear) when we change the desktop display scale to 125%:

                                    The only way to avoid scaling is, as I already wrote, to paint it with 800x800px.

                                    That's what setDevicePixelRatio does.

                                    Christian EhrlicherC Online
                                    Christian EhrlicherC Online
                                    Christian Ehrlicher
                                    Lifetime Qt Champion
                                    wrote on last edited by
                                    #17

                                    @GrecKo said in Image gets de-pixalated or distorted (unclear) when we change the desktop display scale to 125%:

                                    That's what setDevicePixelRatio does.

                                    Did I said something else?
                                    I was (and still am) under the impression that he wants to draw with 1000x1000 ...

                                    Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                                    Visit the Qt Academy at https://academy.qt.io/catalog

                                    1 Reply Last reply
                                    0

                                    • Login

                                    • Login or register to search.
                                    • First post
                                      Last post
                                    0
                                    • Categories
                                    • Recent
                                    • Tags
                                    • Popular
                                    • Users
                                    • Groups
                                    • Search
                                    • Get Qt Extensions
                                    • Unsolved