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

时间:2017-05-09 06:18:14

标签: c++ qt screenshot

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

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

所以我尝试使用/dev/fb0

阅读QFile::readAll
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 ...

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

1 个答案:

答案 0 :(得分:1)

我不确定使用QTextStream并将数据转换为QString然后返回QByteArray是最好的方法。正如所解释in Qt's documentationQString构建QByteArray强制转换为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

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

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

  

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

以下代码是对screenshot example

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