从原始帧缓冲数据获取jpg图像

时间:2013-03-05 10:03:41

标签: java android framebuffer

我能够获得android framebuffer.But我不知道如何将这些原始字节转换为jpg图像文件。如果我尝试使用java bufferedImage.setpixel方法在我的笔记本电脑上绘制图像。我得到错误的彩色图像< / p>

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

1 个答案:

答案 0 :(得分:6)

在android上,帧缓冲区中有2个或更多缓冲的图像。因此,当您复制上面的fb0文件时,其中至少有2个屏幕图像。您可以通过执行以下操作来拆分它们:

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

例如,如果您的设备是480x320,并且像素编码为4个字节,则可以通过以下方式提取2个连续帧:

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

如果fb0帧缓冲区中有3个图像:

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

其中:

  • dd是一个linux实用程序,用于复制和转换带参数的原始文件:

    • if用于“输入文件”
    • of用于“输出文件”
    • bs用于“块大小”。在示例480x4 = 1920(480像素高,每像素4个字节)
    • count用于计算从if读取的“块大小”数,并写入of(即此处我们读取/写入宽度大小)
    • skip第二张图片是要跳过的“块大小”的nb(即从第一张图片跳过count的nb)

您可以通过将块大小设置为480x320x4 = 614400并且count = 1来使用更简单的命令,但是如果您需要动态支持不同的屏幕尺寸,我发现拆分bs和计数在我的示例中更容易使用参数进行编程。

另请注意,如果从设备shell运行上述内容,则设备可能没有dd命令。如果您安装了busybox,则可以将dd替换为busybox dd

图像根据RGB32,BGR32,...像素格式的设备进行编码。您需要重新编码它们以获得JPG或PNG ... 您可以在Stackoverflow上找到使用ffmpeg的示例。一个简单的例子是(对于RGB32设备,屏幕为640x320的屏幕):

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

如果你使用ffmpeg,还有stackoverflow上的帖子指出如何为android构建它(即https://stackoverflow.com/a/9681231/1012381

相关问题