WSS
WSS

Reputation: 513

getting jpg image from raw framebuffer data

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();`

Upvotes: 3

Views: 6056

Answers (1)

JScoobyCed
JScoobyCed

Reputation: 10413

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 )

Upvotes: 6

Related Questions