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. Get Pixel-Values on Screen (KDE)

Get Pixel-Values on Screen (KDE)

Scheduled Pinned Locked Moved Solved General and Desktop
beginnerkdedesktopwindow managerscreenshot
19 Posts 4 Posters 3.4k 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
    wrosecrans
    wrote on 30 Dec 2022, 16:31 last edited by
    #3

    Spectacle is surprisingly complicated to pick apart for a beginner, because it supports some odd features across multiple platforms, in a slightly convoluted way. For basic screenshots, Qt has a simple example: https://doc.qt.io/qt-6/qtwidgets-desktop-screenshot-example.html

    QScreen::grabWindow will do what you want. You can get a screenshot of the whole screen or a specific window's contents. You shouldn't need anything KDE-specific to get started.

    1 Reply Last reply
    2
    • T Offline
      T Offline
      tim-hilt
      wrote on 30 Dec 2022, 20:03 last edited by
      #4

      @wrosecrans thanks for your answer! This is very helpful. Two issues have come up when I tried adapting the code from the Screenshot-Example:

      1. The existing code I'm trying to update with the Screenshot-Example was previously using Qt5. I understand that to use the QScreen::grabWindow()-function, I have to use Qt6. I did install Qt6 on my machine, however when I try to change the CMakeLists.txt from
      find_package (Qt5 REQUIRED COMPONENTS
          Core
          Gui
      )
      
      # ...
      
      target_link_libraries (myprogram
          PUBLIC
              Qt5::Core
              Qt5::Gui
      

      to this:

      find_package (Qt6 REQUIRED COMPONENTS
          Core
          Gui
          Widgets
      )
      
      # ...
      
      target_link_libraries (myprogram
          PUBLIC
              Qt::Core
              Qt::Gui
              Qt::Widgets
      

      I see the following error in CMakes configure-step:

      [cmake] -- Configuring done
      [cmake] CMake Error: The INTERFACE_QT_MAJOR_VERSION property of "Qt6::Widgets" does
      [cmake] not agree with the value of QT_MAJOR_VERSION already determined
      [cmake] for "myprogram".
      
      1. When trying to incorporate the following:
        QScreen *screen = QGuiApplication::primaryScreen();
        auto a = screen->grabWindow(0);
      

      I get red highlighting under the arrow-accessor along with the following error:

      Member access into incomplete type 'QScreen'
      

      I can imagine that the second error will be fixed if get the first error to go away. Any idea on that? Thanks again for your response.

      If you want to take a look at the code, you can find the mentioned snippets here (CMakeLists.txt) and here (Decoration.cc).

      1 Reply Last reply
      0
      • C Offline
        C Offline
        Christian Ehrlicher
        Lifetime Qt Champion
        wrote on 30 Dec 2022, 20:08 last edited by
        #5

        Clean your build directory after switching from Qt5 to Qt6 and use Qt6::Foo instead Qt::Foo to be sure to use the Qt6 libs.

        Member access into incomplete type 'QScreen'

        As always - when you want to use a class you have to include the header where the class is defined.

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

        T 1 Reply Last reply 30 Dec 2022, 20:18
        1
        • C Christian Ehrlicher
          30 Dec 2022, 20:08

          Clean your build directory after switching from Qt5 to Qt6 and use Qt6::Foo instead Qt::Foo to be sure to use the Qt6 libs.

          Member access into incomplete type 'QScreen'

          As always - when you want to use a class you have to include the header where the class is defined.

          T Offline
          T Offline
          tim-hilt
          wrote on 30 Dec 2022, 20:18 last edited by
          #6

          @Christian-Ehrlicher I might really have included the wrong header! Thanks for pointing that out.

          As for the build directory: I see the error even if I delete the build-directory and configure Cmake on a clean slate. Anything else I can check?

          1 Reply Last reply
          0
          • C Offline
            C Offline
            Christian Ehrlicher
            Lifetime Qt Champion
            wrote on 30 Dec 2022, 20:19 last edited by
            #7

            Since you did not show the whole CMakeLists.txt you did not tell us that you're also trying to link against KDE5 libs - this will not work you can't mix Qt5 and Qt6.

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

            T 1 Reply Last reply 30 Dec 2022, 20:30
            0
            • C Christian Ehrlicher
              30 Dec 2022, 20:19

              Since you did not show the whole CMakeLists.txt you did not tell us that you're also trying to link against KDE5 libs - this will not work you can't mix Qt5 and Qt6.

              T Offline
              T Offline
              tim-hilt
              wrote on 30 Dec 2022, 20:30 last edited by
              #8

              @Christian-Ehrlicher does that mean the idea of @wrosecrans won‘t work?

              C 1 Reply Last reply 30 Dec 2022, 20:33
              0
              • T tim-hilt
                30 Dec 2022, 20:30

                @Christian-Ehrlicher does that mean the idea of @wrosecrans won‘t work?

                C Offline
                C Offline
                Christian Ehrlicher
                Lifetime Qt Champion
                wrote on 30 Dec 2022, 20:33 last edited by
                #9

                @tim-hilt said in Get Pixel-Values on Screen (KDE):

                does that mean the idea of @wrosecrans won‘t work?

                It does if you use the qt-5 docs instead the qt-6 ones

                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
                • T Offline
                  T Offline
                  tim-hilt
                  wrote on 30 Dec 2022, 21:25 last edited by
                  #10

                  @Christian-Ehrlicher thanks. That did in fact work.

                  1 Reply Last reply
                  0
                  • T Offline
                    T Offline
                    tim-hilt
                    wrote on 30 Dec 2022, 22:05 last edited by tim-hilt
                    #11

                    @Christian-Ehrlicher @wrosecrans The original question is answered so I marked the thread as solved. However, allow me to ask one more question:

                    My ultimate goal is to find the most prominent color in the first row of pixels in a window. My current, naive implementation looks like this:

                      QScreen *screen = QGuiApplication::primaryScreen();
                      auto window = screen->grabWindow(0).toImage(); // Convert to QImage
                    
                      // I have no way to debug, so I'm logging to journalctl
                      syslog(LOG_NOTICE, "[Window Decoration] Width: %d, Height: %d",
                             window.width(), window.height());
                    
                      std::unordered_map<QRgb, unsigned int> cols{};
                    
                      for (int i = 0; i < window.width(); i++) {
                        cols[window.pixel(i, 0)]++; // Count color-occurences
                      }
                    

                    However the above code always logs, that the window is 0x0 pixels, so no pixel-value can actually be observed. Should I open another thread for this issue? Any idea what could have gone wrong? I added a 500ms delay before calling the above code, but that didn't change the behavior.

                    Here you can see the code in context.

                    M 1 Reply Last reply 30 Dec 2022, 22:35
                    0
                    • T tim-hilt
                      30 Dec 2022, 22:05

                      @Christian-Ehrlicher @wrosecrans The original question is answered so I marked the thread as solved. However, allow me to ask one more question:

                      My ultimate goal is to find the most prominent color in the first row of pixels in a window. My current, naive implementation looks like this:

                        QScreen *screen = QGuiApplication::primaryScreen();
                        auto window = screen->grabWindow(0).toImage(); // Convert to QImage
                      
                        // I have no way to debug, so I'm logging to journalctl
                        syslog(LOG_NOTICE, "[Window Decoration] Width: %d, Height: %d",
                               window.width(), window.height());
                      
                        std::unordered_map<QRgb, unsigned int> cols{};
                      
                        for (int i = 0; i < window.width(); i++) {
                          cols[window.pixel(i, 0)]++; // Count color-occurences
                        }
                      

                      However the above code always logs, that the window is 0x0 pixels, so no pixel-value can actually be observed. Should I open another thread for this issue? Any idea what could have gone wrong? I added a 500ms delay before calling the above code, but that didn't change the behavior.

                      Here you can see the code in context.

                      M Offline
                      M Offline
                      mpergand
                      wrote on 30 Dec 2022, 22:35 last edited by mpergand
                      #12

                      @tim-hilt
                      I'm using this kind of code:

                             QScreen* screen=qApp->primaryScreen();
                             screen=window()->windowHandle()->screen();
                             if(!screen) return;
                             QPoint pt=window()->geometry().topLeft();
                             auto pixmap= screen->grabWindow(this->winId(), pt.x(),pt.y(),300,height());
                             auto color = pixmap.toImage().pixelColor(2,2);
                             qDebug()<<hex<<color<<color.rgb();
                      
                      1 Reply Last reply
                      0
                      • T Offline
                        T Offline
                        tim-hilt
                        wrote on 30 Dec 2022, 23:17 last edited by
                        #13

                        Hi @mpergand, thanks for the reply. It seems like you have an instance of QGuiApplication that you hold in the variable qApp. I unfortunately don't have any of that. I generally don't really understand your code. Why are you initializing screen with one value, if it's directly overwritten in the second line?

                        I logged the screen-name that I get when using QGuiApplication::primaryScreen(). It prints eDP-1, which is my laptop-screen. So I correctly get the screen. The issue thus seems to happen when I use grabWindow. screen->grabWindow(0) should grab the pixels of the entire screen, but that doesn't seem to be the case for me.

                        I also tried screen->grabWindow(QApplication::activeWindow()->winId()) to get the window-id of the currently active window, but that just crashes KDE.

                        I'm unfortunately out of ideas for now. Any idea what else I could try?

                        M 1 Reply Last reply 31 Dec 2022, 00:03
                        0
                        • T tim-hilt
                          30 Dec 2022, 23:17

                          Hi @mpergand, thanks for the reply. It seems like you have an instance of QGuiApplication that you hold in the variable qApp. I unfortunately don't have any of that. I generally don't really understand your code. Why are you initializing screen with one value, if it's directly overwritten in the second line?

                          I logged the screen-name that I get when using QGuiApplication::primaryScreen(). It prints eDP-1, which is my laptop-screen. So I correctly get the screen. The issue thus seems to happen when I use grabWindow. screen->grabWindow(0) should grab the pixels of the entire screen, but that doesn't seem to be the case for me.

                          I also tried screen->grabWindow(QApplication::activeWindow()->winId()) to get the window-id of the currently active window, but that just crashes KDE.

                          I'm unfortunately out of ideas for now. Any idea what else I could try?

                          M Offline
                          M Offline
                          mpergand
                          wrote on 31 Dec 2022, 00:03 last edited by
                          #14

                          @tim-hilt said in Get Pixel-Values on Screen (KDE):

                          Why are you initializing screen with one value, if it's directly overwritten in the second line?

                          You're right, that's old (test) code that I don't use because grab() doesn't work well:

                          • the colors of the grabbed image are ligther then the original
                          • there's a strange redraw bug on the original window after the grab operation (at least on mac)

                          Try with a portion of the screen:
                          auto pixmap= screen->grabWindow(winId,100,100,200,200);

                          In my opinion, the grab method is not really reliable.

                          1 Reply Last reply
                          0
                          • T Offline
                            T Offline
                            tim-hilt
                            wrote on 31 Dec 2022, 08:06 last edited by tim-hilt
                            #15

                            @mpergand the pixmap-size is still 0x0 pixels, even if I call grabWindow with coordinates. In my application I call .toImage() on the returned pixmap. However both the pixmap and the image are both of size 0x0 pixels. So it also doesn't get lost in the conversion-process from pixmap to image.

                            M 1 Reply Last reply 31 Dec 2022, 14:18
                            0
                            • T tim-hilt
                              31 Dec 2022, 08:06

                              @mpergand the pixmap-size is still 0x0 pixels, even if I call grabWindow with coordinates. In my application I call .toImage() on the returned pixmap. However both the pixmap and the image are both of size 0x0 pixels. So it also doesn't get lost in the conversion-process from pixmap to image.

                              M Offline
                              M Offline
                              mpergand
                              wrote on 31 Dec 2022, 14:18 last edited by Christian Ehrlicher
                              #16

                              Test on KDE 21.04 in virtualbox.

                              int main(int argc, char *argv[])
                              {    
                               QApplication app(argc, argv);
                              
                                QWidget w1;
                                w1.show();
                                w1.resize(300,200);
                              
                                QTimer::singleShot(500, 0,[&w1]()
                                   {
                                    QScreen *screen = QGuiApplication::primaryScreen();
                                    auto screen_img = screen->grabWindow(0).toImage();
                                    qDebug()<<screen_img;
                                    auto win_img= screen->grabWindow(w1.winId());
                                    qDebug()<<win_img;
                                   }
                               );
                               return app.exec();
                              }
                              

                              QImage(QSize(1891, 972),format=QImage::Format_RGB32,depth=32,devicePixelRatio=1,bytesPerLine=7564,sizeInBytes=7352208)
                              QPixmap(QSize(300, 200),depth=32,devicePixelRatio=1,cacheKey=0x700000001)

                              Work as expected.

                              T 1 Reply Last reply 31 Dec 2022, 15:31
                              0
                              • M mpergand
                                31 Dec 2022, 14:18

                                Test on KDE 21.04 in virtualbox.

                                int main(int argc, char *argv[])
                                {    
                                 QApplication app(argc, argv);
                                
                                  QWidget w1;
                                  w1.show();
                                  w1.resize(300,200);
                                
                                  QTimer::singleShot(500, 0,[&w1]()
                                     {
                                      QScreen *screen = QGuiApplication::primaryScreen();
                                      auto screen_img = screen->grabWindow(0).toImage();
                                      qDebug()<<screen_img;
                                      auto win_img= screen->grabWindow(w1.winId());
                                      qDebug()<<win_img;
                                     }
                                 );
                                 return app.exec();
                                }
                                

                                QImage(QSize(1891, 972),format=QImage::Format_RGB32,depth=32,devicePixelRatio=1,bytesPerLine=7564,sizeInBytes=7352208)
                                QPixmap(QSize(300, 200),depth=32,devicePixelRatio=1,cacheKey=0x700000001)

                                Work as expected.

                                T Offline
                                T Offline
                                tim-hilt
                                wrote on 31 Dec 2022, 15:31 last edited by tim-hilt
                                #17

                                @mpergand can you provide a CMakeLists.txt or the compile-command you used?

                                and just to make that clear: I’m using the same code distilled to

                                QScreen *screen = QGuiApplication::primaryScreen();
                                auto screen_img = screen->grabWindow(0).toImage();
                                

                                So no app.exec or something like that. That shouldn’t matter however, since screen->name did resolve to the expected screen name.

                                If you have the capacity, you could try running my code (linked above). It‘s actually a window-decoration for KDE! The Readme contains installation-instructions and I added logs that you can read through journalctl.

                                1 Reply Last reply
                                0
                                • T Offline
                                  T Offline
                                  tim-hilt
                                  wrote on 1 Jan 2023, 19:57 last edited by tim-hilt 1 Jan 2023, 19:58
                                  #18

                                  Some more news about this:

                                  1. I used qDebug to log the returned object for QScreen::grabWindow. It prints QPixmap(null)! So the grabWindow-function doesn't seem to work on my machine. Versions are printed below.
                                  2. I can observe the same behavior when compiling and running the Screenshot-Example that you guys were referring to earlier. When I execute the compiled binary and try to take a screenshot, this is the output I'm getting:
                                  $ ./screenshot
                                  QPixmap::scaled: Pixmap is a null pixmap
                                  QPixmap::scaled: Pixmap is a null pixmap
                                  QPixmap::scaled: Pixmap is a null pixmap
                                  

                                  Versions:

                                  qt5-base: 5.15.7+kde+r177-1
                                  kwin_wayland --version: kwin 5.26.4
                                  plasmashell --version: plasmashell 5.26.4
                                  uname -a: Linux t14s 6.1.1-arch1-1 #1 SMP PREEMPT_DYNAMIC Wed, 21 Dec 2022 22:27:55 +0000 x86_64 GNU/Linux
                                  

                                  @Christian-Ehrlicher can you give me your guess as to where this issue should be further pursued? Is it likely due to Arch Linux, KDE or Qt?

                                  1 Reply Last reply
                                  0
                                  • T Offline
                                    T Offline
                                    tim-hilt
                                    wrote on 1 Jan 2023, 21:09 last edited by
                                    #19

                                    I have since found out that grabWindow doesn’t work under Wayland. So I either have to find another way or resort to X11 again.

                                    1 Reply Last reply
                                    0

                                    12/19

                                    30 Dec 2022, 22:35

                                    • Login

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