はじめに
フレームバッファ(/dev/fb0) + python3でスクリーンショットを撮ります。
準備
Piilow(画像処理ライブラリ)をインストールする
pip install Pillow
フレームバッファの情報を取得する
fbset ↓結果 mode "1920x1080" geometry 1920 1080 1920 1080 32 timings 0 0 0 0 0 0 0 rgba 8/16,8/8,8/0,8/24
上記から読み取れるもの
- 幅1920
- 高さ1080
- 32bit → 1pixelの色は32bit(4byte)
- rgba
rgba 8/16,8/8,8/0,8/24 となっていますが、これは
r → 8/16:32bitの左16bit目から8bit
g → 8/8:32bitの左8bit目から8bit
b → 8/0:32bitの左0bit目から8bit
a → 8/24:32bitの左24bit目から8bit
となっていますので、32bitの中身はbgraの順にデータが並んでいることになります。
/dev/fb0 には bgraの順番で32bit(4byte)のデータが1920×1080個並んでいることになります。
コード
from PIL import Image #1 file = open('/dev/fb0','rb') #2 rawdata = file.read() file.close() Imagesize = (1920,1080) tmpImg = Image.frombytes('RGBA', Imagesize, rawdata) #3 r, g, b, a = tmpImg.split() #4 img = Image.merge("RGB", (b, g, r)) #5 img.save(img.png) #6
- #1 開発が停止したPILのフォークがPillowで、互換性があるようにPILからimportするのかな?最初 from Pillow としてしばらく悩んでました
- #2 /dev/fb0をバイナリで読み込む
- #3 rawdata(中身/dev/fb0)をRGBAモードで読み込む(BGRAモードはない)
- #4 イメージをrgbaのチャンネルごとに分割する
- #5 BGRAをRGBAで読み込んでいるため、bとrが入れ替わっているのでここで入れ替える。(“RGBA”, (b, g, r, a))じゃないの?と思うかもしれませんが、正しいイメージにならないことがあったのでaを省いた。原因はしらべていません。
- #6 拡張子をjpgにしても適当に変換して保存してくれる。ちなみにa.saveとするとaチャンネルの画像が保存できる
最後に
端末ウィンドウをぐりぐりマウスで移動させながらスクリーンショットを撮ると端末ウィンドウの表示が歪んでしまいました。
これは/dev/fb0を読込んでいる途中で/dev/fb0が更新されるためだと思われます。
なのでアクションゲームなどのスクリーンショット撮影には向かないと思います。
今回はとある検査機器のUI(ラズパイで制御、アニメーションとかは無い)のスクリーンショットを撮りたかっただけなので特に問題ありませんでした。