我知道之前已经问过这个问题。原始帖子在这里how to convert 16-bit RGB Frame Buffer to a viewable format?但我没有得到我的欲望输出。
目前我正在处理帧缓冲区。确切的图片是我正在访问Android手机的帧缓冲区(/ dev / graphics / fb0)(通过“adb”shell)。我使用“dd”来获取帧缓冲区。
cd /dev/graphics
dd if=fb0 of=/sdcard/fb0.raw bs=1 count=width*height*3 //this width and height are based on mobile screen specification. And 3 is for RGB888
我使用了这段代码 -
#include <stdio.h>
#include <stdlib.h>
#include <bmpfile.h>
int main(int argc, char **argv)
{
bmpfile_t *bmp;
int i, j;
char* infilename;
FILE* infile;
char* outfile;
int width;
int height;
int depth;
unsigned char red, green, blue; // 8-bits each
unsigned short pixel; // 16-bits per pixel
//rgb_pixel_t bpixel = {128, 64, 0, 0};
//make && ./raw565tobmp fb.rgb565 720 480 32 fb.bmp && gnome-open fb.bmp
if (argc < 6) {
printf("Usage: %s infile width height depth outfile.\n", argv[0]);
exit(EXIT_FAILURE);
}
infilename = argv[1];
outfile = argv[5];
infile = fopen(infilename, "rb");
if (NULL == infile) {
perror("Couldn't read infile");
exit(EXIT_FAILURE);
}
width = atoi(argv[2]);
height = atoi(argv[3]);
depth = atoi(argv[4]);
// should be depth/8 at 16-bit depth, but 32-bit depth works better
short buffer[height*width*(depth/16)];
printf("depth: %d", depth);
if (fread(&buffer, 1, height*width*(depth/16), infile) != height*width*(depth/16)) {
fputs("infile dimensions don't match the size you supplied\n", stderr);
}
printf("depth: %d", depth);
if ((bmp = bmp_create(width, height, depth)) == NULL) {
printf("Invalid depth value: '%d'. Try 1, 4, 8, 16, 24, or 32.\n", depth);
exit(EXIT_FAILURE);
}
for (i = 0; i < width; ++i) { // 720
for (j = 0; j < height; ++j ) { // 480
pixel = buffer[width*j+i];
red = (unsigned short)((pixel & 0xFF0000) >> 16); // 8
green = (unsigned short)((pixel & 0x00FF00) >> 8); // 8
blue = (unsigned short)(pixel & 0x0000FF); // 8
rgb_pixel_t bpixel = {blue, green, red, 0};
bmp_set_pixel(bmp, i, j, bpixel);
}
}
bmp_save(bmp, outfile);
bmp_destroy(bmp);
return 0;
}
此计划的输入 - ./a.out fb0.raw 480 854 24 /data/new.bmp
argv [1] =输入文件
的argv [2] =宽度
的argv [3] =高度
的argv [4] =深度
argv [5] =输出文件
最初代码是how to convert 16-bit RGB Frame Buffer to a viewable format?
现在打开bmp文件后,我得到的每件事都是黑色。为什么会这样?
如何显示帧缓冲区?
答案 0 :(得分:1)
为了获得大量的便利和功能,你可以使用OpenCV Port for android。那么这将是最简单的事情之一。我不认为这会是一个很大的问题,因为你在项目中使用了natice代码。
如果我没记错的话,该函数名为imwrite()
,位于HighGui.hpp
您可以在此处找到OpenCV的Android端口:http://opencv.org/downloads.html
相关的“黑度”问题:我在处理pgm图像时遇到了这个问题。 PGM标题必须为图像指定“最大”深度。例如。 255,8位。想象一下,你有8位数据,但使用最大分辨率为16位,65565个值。图片将是“黑色”,因为所有的价值都很低。我希望你知道我的意思。
答案 1 :(得分:1)
我一直在尝试捕获Android 2.3.4移动屏幕图像并遇到同样的问题。首先,我尝试使用一些工具,但我让一切变得复杂。
Joe给了我关于填充的线索,所以我只是尝试在文件中读取原始帧缓冲区,用GIMP加载它(在这一刻我对制作软件不感兴趣,可能在以后)。
使用GIMP原始导入参数我发现,对于填充,240x320屏幕的宽度实际上是256x320,右侧是透明填充。它也不是RGB而是&#34; RGB Alpha&#34;原始类型。
正如我正在处理的是一本手册,以下内容以及GIMP足以在旧的Android版本上运行:
adb shell "cat /dev/graphics/fb0 > /mnt/sdcard/documents/devimages/$1.data" adb pull /mnt/sdcard/documents/devimages/$1.data adb shell "rm /mnt/sdcard/documents/devimages/$1.data"
我希望这有助于某人: - )
答案 2 :(得分:0)
rgb_pixel_t bpixel = {blue, green, red, 0};
可能将alpha值设置为0,alpha是透明度值。尝试255,看看你是否得到任何结果。如果你的像素方程有误,你至少应该得到一些东西。
图像的另一个“问题”是,有时数据不会存储为RGBRGBRGB ...而是存储在Microsoft / IBM DIB中的BGRBGRBGR。这是一个简单的检查,因为你会得到图像,但它就像你在LSD。
height*width*(depth/16)
还应该看一下。我还建议将其放入一个变量中,以便您更容易维护。
另外,有一点要注意RAW DIB:有时它们每行都有一个设置填充。在MS / IBM DIB中,要求每条扫描线必须以4字节为增量进行存储。所以,如果你的输出转向一个方向很多,那可能就是这样。在某些情况下,图像会颠倒存储
答案 3 :(得分:0)
为了不重新发明轮子,我试图重新使用现有的工具:
获取帧缓冲:
adb pull /dev/graphics/fb0 androidFB
查找framebuffer文件中使用的格式。我为此目的使用实用程序avconv(但你也可以使用ffmpeg),与自制脚本相关联:
#!/bin/bash
#Change FB_RESOLUTION value by the android device's resolution
FB_RESOLUTION=240x320
OUTPUT_DIR=fbresult
#format come from: avconv -pix_fmts| cut -f 2 -d " "
format=(yuv420p yuyv422 rgb24 bgr24 yuv422p yuv444p yuv410p yuv411p gray monow monob pal8 yuvj420p yuvj422p yuvj444p xvmcmc xvmcidct uyvy422 uyyvyy411 bgr8 bgr4 bgr4_byte rgb8 rgb4 rgb4_byte nv12 nv21 argb rgba abgr bgra gray16be gray16le yuv440p yuvj440p yuva420p vdpau_h264 vdpau_mpeg1 vdpau_mpeg2 vdpau_wmv3 vdpau_vc1 rgb48be rgb48le rgb565be rgb565le rgb555be rgb555le bgr565be bgr565le bgr555be bgr555le vaapi_moco vaapi_idct vaapi_vld yuv420p16le yuv420p16be yuv422p16le yuv422p16be yuv444p16le yuv444p16be vdpau_mpeg4 dxva2_vld rgb444le rgb444be bgr444le bgr444be y400a bgr48be bgr48le yuv420p9be yuv420p9le yuv420p10be yuv420p10le yuv422p10be yuv422p10le yuv444p9be yuv444p9le yuv444p10be yuv444p10le yuv422p9be yuv422p9le vda_vld gbrp gbrp9be gbrp9le gbrp10be gbrp10le gbrp16be gbrp16le)
mkdir $OUTPUT_DIR
for item in ${format[*]}
do
#Loop through operation
avconv -vframes 1 -f rawvideo -pix_fmt $item -s $FB_RESOLUTION -i androidFB $OUTPUT_DIR/$item.png
done
浏览OUTPUT_DIR目录以查找具有正确外观的图像。该文件的名称是使用的格式:XXXX.png使用的格式为XXXX
您现在可以使用以下命令转换PNG中的帧缓冲区(不要忘记替换分辨率FB_RESOLUTION并使用正确的值格式化XXXX)
avconv -vframes 1 -f rawvideo -pix_fmt XXXX -s FB_RESOLUTION -i androidFB androidFB.png