3

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

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

1 回答 1

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 个字节)
    • countif是计算要读取和写入多少“块大小” of(即在这里我们读/写宽度大小)
    • skip第二张图片是要跳过的“块大小”的 nb(即count从第一张图像中跳过 nb)

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

另请注意,如果您从设备外壳运行上述命令,您的设备可能没有该dd命令。如果您安装了busybox,则可以替换ddbusybox dd

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

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

于 2013-03-09T14:19:59.613 回答