如何使用Qt读取我的应用程序屏幕像素数据

How to read my application screen pixel data with Qt

本文关键字:屏幕 像素 像素数 数据 应用程序 我的 何使用 Qt 读取      更新时间:2023-10-16

我正在尝试在我的Qt Qml应用程序中读取我的应用程序屏幕像素数据。

第一种方法是grabToImage(),这在我的 PC 中很快。但同样需要几秒钟才能在我的嵌入式设备中抓取图像。

所以我试着用QFile::readAll来阅读/dev/fb0

QFile file("/dev/fb0");
QFile dataFile("/home/icu/WorkSpace/Samples/FBRead/Exe/data.bin");
if(!file.open(QIODevice::ReadOnly))
{
qDebug() << Q_FUNC_INFO << file.errorString();
}
if(!dataFile.open(QIODevice::WriteOnly))
{
qDebug() << Q_FUNC_INFO << dataFile.errorString();
}
QTextStream in(&file);
QString data;
qDebug() << Q_FUNC_INFO << "start read";
//    while(!in.atEnd())
//    {
qDebug() << Q_FUNC_INFO << "read";
data = in.readAll();
//        qDebug() << Q_FUNC_INFO << data;
//    }
QByteArray dataBytes;
dataBytes.append(data);
dataFile.write(dataBytes);
file.close();
dataFile.close();

我尝试使用一些显示从原始文件读取图像的工具打开文件。但它没有显示任何数据。当我打开文件数据时,就像01 01 01 00 01 01 01 00 ...

有没有其他方法可以快速读取我的屏幕像素数据?谢谢

我不确定使用QTextStream将数据转换为QString然后又转换为QByteArray是否是最好的方法。正如Qt的文档中所解释的,从QByteArray构造QString会强制转换为UTF-8,并且在第一个空字符处停止复制,因此您正在修改像素数据而不是完全获取它。请尝试直接在文件之间复制数据:

bool grabScreenToFile(const QString& outPath) {
QFile inFile("/dev/fb0");
QFile outFile(outPath);
// ...
outFile.write(inFile.readAll());
return true;
}

要检查这是否复制了文件的实际内容并且您没有问题(截断、转换等),请与使用cat /dev/fb0 > grab.raw获得的文件进行比较(请注意,它不是 JPEG 或 PNG 图像,而是原始缓冲区)。

/

dev/fb0

此链接包含有关从/dev/fb0设备获取帧缓冲的详细说明。基本上,它指出您必须注意缓冲区的深度,因为像素可能以不同的方式打包。


另一方面,您是否尝试过Qt提供的其他抓取方法,例如QScreen::grabWindow?也许它的性能比 QML 的QQuickItem::grabToImage更好(我猜你正在使用的那个)。事实上,文档指出:

此函数会将项目渲染到屏幕外的表面,并将该表面从 GPU 的内存复制到 CPU 的内存中,这可能非常昂贵。

以下代码是对屏幕截图示例的修改。

auto screen = QGuiApplication::primaryScreen();
if (const QWindow *window = windowHandle()) {
screen = window->screen();
}
if (screen) {    
const auto pixmap = screen->grabWindow(yourWidget->winId());
// ...
}