3

I m able to get android framebuffer.But I do not know how to convert those raw bytes into jpg image file.If I try to draw image on my laptop with java bufferedImage.setpixel method.I m getting incorrect colored image

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();`
WSS
  • 503
  • 5
  • 20
  • I'll just point out that attempting to capture the screen contents in this way isn't recommended. Even if you're root there are devices where this simply may not be supported. See e.g. [this post by one of the NDK developers at Google](https://groups.google.com/forum/?fromgroups=#!topic/android-ndk/j438Uyfmy78) – Michael Mar 09 '13 at 14:31

1 Answers1

6

On android, the frame buffer has 2 or more image buffered in it. So when you copy as above the fb0 file, there are at least 2 screens images in it. You could split them by doing something like:

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

So for example, if your device is a 480x320, and a pixel encoded on 4 bytes, you can extract 2 sequential frames by:

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

If there were 3 images in the fb0 frame buffer:

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

Where:

  • dd is a linux utility to copy and convert raw files with parameters:

    • if is for 'input file'
    • of is for 'output file'
    • bs is for 'block size'. In the example 480x4=1920 (480 pixel high, 4 byes per pixel)
    • count is to count how many 'block size' to read from if and write to of (i.e. here we read/write the width size)
    • skip for the second picture is the nb of 'block size' to skip (i.e. skip the nb of count from first image)

You could use a simpler command by setting block size to 480x320x4=614400 and count=1 but if you need to dynamically support different screen sizes I found splitting bs and count as in my example easier to program with parameters.

Also note that if you run the above from the device shell, your device might not have the dd command. If you installed busybox you can replace dd by busybox dd

The images are encoded depending on your device in RGB32, BGR32,... pixel format. You need to re-encode them to get a JPG or PNG... There are examples using ffmpeg on Stackoverflow that you can probably find. A quick example is (for the case of a RGB32 device, screen sixe of 480x320):

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

If you go with ffmpeg, there are also posts on stackoverflow that point how to build it for android (i.e. https://stackoverflow.com/a/9681231/1012381 )

Community
  • 1
  • 1
JScoobyCed
  • 10,203
  • 6
  • 34
  • 58
  • thanx for your precious answer.But i did not understand your above four line code ex:-keywords(dd,bs,count).Could u explain it in a simpler way?And also these 2 or more frame buffer images are of the same time of device screen or sequential?And how to know length of each framebuffer image? – WSS Mar 19 '13 at 17:03