2017-05-09 56 views
1

Qt Qmlアプリケーションでアプリケーション画面のピクセルデータを読み込もうとしています。Qtでアプリケーション画面のピクセルデータを読み取る方法

最初のアプローチはgrabToImage()で、私のPCで高速です。しかし、同じことが、組み込み機器で画像を取得するのに数秒かかることもあります。

だから、私は、画像をRAWファイルからの読み込みを示すいくつかのツールを使用してファイルを開こうとしました、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 ...

私の画面のピクセルデータを高速に読み取る方法はありますか?ありがとう

答えて

1

を使用し、QStringにデータを変換してからQByteArrayに戻すことが最良の方法であるかどうかわかりません。説明の通りin Qt's documentationQStringQByteArrayから作成すると、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デバイスからフレームバッファをつかんに関する長い説明が含まれています。基本的に、ピクセルはさまざまな方法でパックされるため、バッファの深さに注意する必要があることを指摘します。一方


、あなたがそのようなQScreen::grabWindowなどのQtで提供つかむ方法、のいずれかの他のを試してみましたか? 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()); 
    // ... 
} 
+0

上記のようにファイル書き込みメソッドを試しましたが、出力ファイルに違いはありませんでした。私は今グラブウインドウをチェックします。 :)ポストのおかげで。 – Abin

+0

ああ、もう1つはパフォーマンスを改善してくれることを願っています...フレームバッファのフォーマットに関する2つのオプションを含める答えを更新しました。 – cbuchart

+0

私は2番目のオプションを試してみましたが、私のPCでは高速ですが、埋め込みデバイスで同じものを実行すると、 'grabwindow()'はnullを返します。私のコードは 'QScreen * screen = QGuiApplication :: primaryScreen();です。 QPixmap pixmap = QPixmap(); QTimeタイマー。 タイマー。開始(); pixmap = screen-> grabWindow(0); qDebug()<< Q_FUNC_INFO << "時間経過" << timer.elapsed()<< "ms"; qDebug()<< Q_FUNC_INFO << "pixmapがnullです" << pixmap.isNull(); qDebug()<< Q_FUNC_INFO << ""は "<< pixmap.save("/opt/img.png ");は保存されています。 qDebug()<< Q_FUNC_INFO << "Exit"; ' – Abin

関連する問題