3

android framebufferを取得できますが、それらの生のバイトをjpg画像ファイルに変換する方法がわかりません。javabufferedImage.setpixelメソッドを使用してラップトップで画像を描画しようとすると、間違った色の画像が表示されます。

Process sh = Runtime.getRuntime().exec("su", null,null);    
OutputStream  os = sh.getOutputStream();
os.write("/system/bin/cat /dev/graphics/fb0 > /sdcard/img.raw".getBytes());
os.flush();          
os.close();
sh.waitFor();`
4

1 に答える 1

6

Androidでは、フレームバッファに2つ以上の画像がバッファリングされています。したがって、上記のようにfb0ファイルをコピーすると、少なくとも2つの画面イメージが含まれます。次のようなことを行うことで、それらを分割できます。

dd if=/sdcard/img.raw bs=<width_of_your_screen> \
   count=<height_of_your_screen> of=/sdcard/img-1.raw
dd if=/sdcard/img.raw bs=<width_of_your_screen> \
   count=<times height_of_your_screen> skip=<previous count> of=/sdcard/img-2.raw

したがって、たとえば、デバイスが480x320で、ピクセルが4バイトでエンコードされている場合、次の方法で2つの連続するフレームを抽出できます。

dd if=/sdcard/img.raw bs=1920 count=320 of=/sdcard/img-1.raw
dd if=/sdcard/img.raw bs=1920 count=320 skip=320 of=/sdcard/img-2.raw

fb0フレームバッファに3つの画像があった場合:

dd if=/sdcard/img.raw bs=1920 count=320 skip=640 of=/sdcard/img-3.raw

どこ:

  • ddパラメータを使用してrawファイルをコピーおよび変換するLinuxユーティリティです。

    • if'入力ファイル'用です
    • of'出力ファイル'用です
    • bs'ブロックサイズ'用です。例では、480x4 = 1920(高さ480ピクセル、ピクセルあたり4バイ)
    • countif読み取りおよび書き込みを行う「ブロックサイズ」の数をカウントすることofです(つまり、ここでは幅サイズの読み取り/書き込みを行います)
    • skipcount2番目の画像は、スキップする「ブロックサイズ」のnbです(つまり、最初の画像からのnbをスキップします)

ブロックサイズを480x320x4=614400およびcount=1に設定することで、より簡単なコマンドを使用できますが、さまざまな画面サイズを動的にサポートする必要がある場合は、例のようにbsとcountを分割してパラメーターを使用してプログラミングする方が簡単です。

また、デバイスシェルから上記を実行した場合、デバイスにddコマンドがない可能性があることにも注意してください。あなたがbusyboxをインストールした場合、あなたは次のように置き換えることができddますbusybox dd

画像は、デバイスに応じてRGB32、BGR32、...ピクセル形式でエンコードされます。JPGまたはPNGを取得するには、それらを再エンコードする必要があります... Stackoverflowでffmpegを使用した例がおそらく見つかります。簡単な例は次のとおりです(RGB32デバイスの場合、480x320の画面6):

ffmpeg -vframes 1 -vcodec rawvideo -f rawvideo -pix_fmt rgb32 -s 480x320 -i img-1.raw -f image2 -vcodec mjpeg img-1.jpg

ffmpegを使用する場合は、Android用にビルドする方法を示すstackoverflowに関する投稿もあります(例:https://stackoverflow.com/a/9681231/1012381

于 2013-03-09T14:19:59.613 に答える