Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/71.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 如何将原始RGB帧缓冲区文件转换为可视格式?_Android_C_Adb_Rgb_Bmp - Fatal编程技术网

Android 如何将原始RGB帧缓冲区文件转换为可视格式?

Android 如何将原始RGB帧缓冲区文件转换为可视格式?,android,c,adb,rgb,bmp,Android,C,Adb,Rgb,Bmp,我知道以前有人问过这个问题。原始线程在这里,但我没有得到我的愿望输出 目前我正在处理帧缓冲区。确切的情况是,我正在访问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 speci

我知道以前有人问过这个问题。原始线程在这里,但我没有得到我的愿望输出

目前我正在处理帧缓冲区。确切的情况是,我正在访问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;
}
#包括
#包括
#包括
int main(int argc,字符**argv)
{
bmpfile_t*bmp;
int i,j;
字符*填充名;
文件*填充;
字符*输出文件;
整数宽度;
内部高度;
智力深度;
无符号字符红色、绿色、蓝色;//每个字符8位
无符号短像素;//每像素16位
//rgb_pixel_t bpixel={128,64,0,0};
//使&&./raw565tobmp fb.rgb565 720 480 32 fb.bmp&&gnome打开fb.bmp
如果(argc<6){
printf(“用法:%s填充宽度高度深度输出文件。\n”,argv[0]);
退出(退出失败);
}
infilename=argv[1];
outfile=argv[5];
infile=fopen(infilename,“rb”);
if(NULL==infle){
perror(“无法阅读内嵌”);
退出(退出失败);
}
宽度=atoi(argv[2]);
高度=atoi(argv[3]);
深度=atoi(argv[4]);
//16位深度时深度应为/8,但32位深度效果更好
短缓冲区[高度*宽度*(深度/16)];
printf(“深度:%d”,深度);
如果(fread(&缓冲区,1,高度*宽度*(深度/16),填充)!=高度*宽度*(深度/16)){
fputs(“填充尺寸与您提供的尺寸不匹配”,stderr);
}
printf(“深度:%d”,深度);
如果((bmp=bmp\u创建(宽度、高度、深度))==NULL){
printf(“无效的深度值:“%d”。请尝试1、4、8、16、24或32。\n”,深度);
退出(退出失败);
}
对于(i=0;i>16);//8
绿色=(无符号短)((像素&0x00FF00)>>8);//8
蓝色=(无符号短)(像素&0x0000FF);//8
rgb_pixel_t bpixel={蓝色,绿色,红色,0};
bmp_设置_像素(bmp,i,j,bpixel);
}
}
bmp_保存(bmp,输出文件);
bmp_破坏(bmp);
返回0;
}
此程序的输入-./a.out fb0.raw 480 854 24/data/new.bmp

argv[1]=输入文件

argv[2]=宽度

argv[3]=高度

argv[4]=深度

argv[5]=输出文件

最初代码在这里给出

现在在这里打开bmp文件后,我得到的所有东西都是黑色的。为什么会这样

如何显示帧缓冲区

  rgb_pixel_t bpixel = {blue, green, red, 0};
可能正在将alpha值设置为0,alpha是透明度值。试试255,看看是否有结果。如果你的像素方程错了,你至少应该得到一些东西

图像的另一个“陷阱”是,有时数据不存储为RGBRGBRGB。。。但BGRBGRBGR与Microsoft/IBM DIB类似。这是一个简单的检查,因为你会得到图像,但它会像你在LSD

height*width*(depth/16)
也应该看看。我还建议将其放入变量中一次,以便更容易维护


另外,对于原始DIB,有一件事需要注意:有时每行都有一组填充。在MS/IBM DIB中,要求每个扫描线必须以4字节的增量存储。所以,如果你的输出经常向一个方向移动,它可能就是那个方向。在某些情况下,图像是颠倒存储的

为了获得许多方便性和功能性,您可以使用android的OpenCV端口。那么这将是最简单的事情之一。我不认为这会是一个很大的问题,因为你在你的项目中使用国家代码

如果我没记错的话,函数名为
imwrite()
,位于HighGui.hpp中

您可以在此处找到OpenCV的android端口:


相关的“黑度”问题:我在处理pgm图像时遇到了这个问题。PGM标头必须为图像指定“最大”深度。例如255,8比特。假设您有8位数据,但最大分辨率为16位,65565个值。图片将是“黑色”,因为所有的值都很低。我希望你明白我的意思。

为了不重新发明轮子,我尝试重新使用现有的工具:

  • 获取帧缓冲区:

    adb pull /dev/graphics/fb0 androidFB
    
  • 查找帧缓冲区文件中使用的格式。为此,我使用实用程序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\U分辨率和格式XXXX)


  • 我一直在尝试拍摄Android 2.3.4手机屏幕图像,但也遇到了同样的问题。首先我试着用一些工具,但我把一切都复杂化了

    Joe给了我关于填充的线索,所以我只是尝试读取一个文件中的原始帧缓冲区,用GIMP加载它(在这一刻,我对为它制作软件不感兴趣,可能以后)

    在使用GIMP原始导入参数时,我发现有了填充,240x320屏幕的宽度实际上是256x320,右边是透明填充。而且它不是RGB而是“RGB Alpha”原始类型

    由于我正在编写的是一本手册,以下内容以及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" adb shell“cat/dev/graphics/fb0>/mnt/sdcard/documents/devimages/$1.data” adb pull/mnt/sdcard/documents/DeviceMages/$1.5数据 adb shell“rm/mnt/sdcard/documents/DeviceMages/$1.数据”
    我希望这对某人有所帮助:-)

    我尝试使用255而不是0,但没有成功。我得到的是黑色。上面的输入不是我唯一尝试的输入。我尝试了不同的深度、宽度和高度值,但不幸的是最终结果是黑屏。你能发布图像的二进制样本吗? 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"