如何访问屏幕上呈现的原始小部件像素?

How to access the raw widget pixels rendered on the screen?

我正在尝试从每一帧中提取像素数据,但是当我尝试获取 pixmap 时,它 return 为空。我以为 pixmap 会 return 屏幕上的实际像素数据,类似于 glReadPixels 但我想我错了。我认为这是为了访问 setPixmap.

结果的像素图

有没有办法访问屏幕上呈现的原始像素?在下面的示例中,“Hello World”呈现在屏幕上,我想要该标签的实际像素数据。

QWidget window;
window.resize(1280, 720);
window.show();
window.setWindowTitle(QApplication::translate("toplevel", "Top-Level Widget"));

QLabel *label = new QLabel(QApplication::translate("label", "Hello World"), &window);
label->move(500, 500);
label->raise();
label->show();
QPixmap pixmapVal = label->pixmap(Qt::ReturnByValue);

原因

QPixmap:

The QPixmap class is an off-screen image representation that can be used as a paint device

换句话说,它是一幅画 canvas,和其他任何画一样 canvas,如果您没有在上面画画,它就是空的。

另一方面,QLabel 用作像素图的视图,而不是其内容,当您尝试访问 label 的像素图而没有设置时,它 returns null.

解决方案

当然有一种方法可以制作一个小部件,你的情况下的标签,像素图的内容和访问像素数据。我解决这个问题的方法是这样的:

  1. 创建一个空 pixmap,其大小为您要访问的 widget 谁的像素内容,例如:

     QPixmap pixmap(widget->size());
    
     pixmap.fill(Qt::transparent);
    
  2. 使用QWidget::render将小部件的内容渲染到像素图上:

     widget->render(&pixmap);
    
  3. 将像素图转换为 QImage 并使用 QImage::pixel or QImage::pixelColor 访问 (pixelX, pixelY) 处像素的 rgb 数据,如下所示:

     pixmap.toImage().pixelColor(pixelX, pixelY);
    

例子

这是我为您准备的示例,用于演示如何实施建议的解决方案:

#include "MainWindow.h"
#include <QApplication>
#include <QLabel>
#include <QDebug>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QWidget w;
    auto *label = new QLabel(QObject::tr("Hello World"), &w);

    label->move(500, 500);
    label->raise();

    w.setWindowTitle(QObject::tr("Top-Level Widget"));
    w.resize(1280, 720);
    w.show();

    QPixmap pixmap(label->size());

    pixmap.fill(Qt::transparent);

    label->render(&pixmap);

    int pixelX = 10;
    int pixelY = 5;

    // Access image pixels
    qDebug() << pixmap.toImage().pixelColor(pixelX, pixelY);

    return a.exec();
}

结果

对于 (10, 5) 处的像素,示例生成以下结果:

QColor(ARGB 1, 0, 0, 0.156863)