10

How to capture the Android device screen content using /dev/graphics/fb0 and how to make it an image file using the collected data from frame buffer. I know for this it requires the device to be rooted and I am ok with that.

Thanks in advance,

venkatvb
  • 681
  • 1
  • 9
  • 24
manju
  • 847
  • 3
  • 16
  • 43

5 Answers5

13

This should work:

adb pull /dev/graphics/fb0 fb0
ffmpeg -vframes 1 -vcodec rawvideo -f rawvideo -pix_fmt rgb32 -s 320x480 -i fb0 -f image2 -vcodec png image.png
nebkat
  • 8,445
  • 9
  • 41
  • 60
  • 1
    Worked great for me, no need to add -vframes 1 – Kevin Parker Feb 25 '14 at 05:13
  • I am getting this as a error : [image2 @ 0x2405c40] Could not get frame filename number 2 from pattern 'image.png' (either set updatefirst or use a pattern like %03d within the filename pattern) av_interleaved_write_frame(): Invalid argument – Santhanam Apr 21 '15 at 13:39
  • I run `adb pull /dev/graphics/fb0 fb0 ` got `adb: error: remote object '/dev/graphics/fb0' does not exist`. And `adb shell;su;cp /dev/graphics/fb /sdcard/` got `cp: /dev/graphics/fb0: No such device` – user3875388 Jan 15 '19 at 06:58
5

If you have the root privilege.

  1. copy data from fb0 to another file, e.g.

    cat fb0 > tmp
    
  2. At this point, you still can't open the new file. because the data structure of the the file cannot met any image file format. So what you need is to decode it. In that file, every two bytes describe a pixel. the higher 5 bites represent the red color, the lower 5bites represent the blue color and the rest middle 6 bites are green. you can use the info above to build a BMP and any other visible file.

Cody Gray - on strike
  • 239,200
  • 50
  • 490
  • 574
Andrew
  • 51
  • 1
  • 1
4

Nebkat's solution works sometimes, but, in working on the Dollop test tool, I've learned that there is no universal way for making an image directly from fb0. The Motorola Droid 2 uses RGB 32. The Huawei Ascend uses RGB 565. The Samsung Captivate uses neither and doesn't appear to put the entire screen in the buffer.

  • All you have to do is change rgb32 into whatever you use. – nebkat Oct 08 '11 at 08:36
  • Yes, the need to change the encoding and the dimensions will be obvious to most readers, now that I've pointed out that not all devices have the same encoding. The FFmpeg approach won't work with the Captivate and others like it, however. – Brian Kyckelhahn Oct 08 '11 at 17:06
  • Thanks! The Jellybean (Android 4.2) emulator used rgb565. – BVB Jun 19 '13 at 20:01
2

If you are not sure about the format of your device frame buffer you can iterate ffmpeg supported formats as follows:

for fmt in $(ffmpeg -pix_fmts|cut -d " " -f 2); do ffmpeg -vcodec rawvideo -f rawvideo -pix_fmt $fmt -s 320x480 -i fb0 -f image2 -vcodec png /tmp/image-$fmt.png; done

The outcome thumbnails are also kind of artistic.

1

You might want to replace -pix_fmt rgb32 with -pix_fmt rgb565le for 16-bit devices.

gilm
  • 7,690
  • 3
  • 41
  • 41