Reputation: 513
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
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