Get Pixel-Values on Screen (KDE)
-
@Christian-Ehrlicher does that mean the idea of @wrosecrans won‘t work?
-
@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
-
@Christian-Ehrlicher thanks. That did in fact work.
-
@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.
-
@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();
-
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 printseDP-1
, which is my laptop-screen. So I correctly get the screen. The issue thus seems to happen when I usegrabWindow
.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?
-
@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.
-
@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. -
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.
-
@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.
-
Some more news about this:
- I used
qDebug
to log the returned object forQScreen::grabWindow
. It printsQPixmap(null)
! So thegrabWindow
-function doesn't seem to work on my machine. Versions are printed below. - 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?
- I used