广

android开发

  • IOS开发
  • android开发
  • PHP编程
  • JavaScript
  • ASP.NET
  • ASP编程
  • JSP编程
  • Java编程
  • 易语言
  • Ruby编程
  • Perl编程
  • AJAX
  • 正则表达式
  • C语言
  • 编程开发

    Android模拟器中窗口截图存成文件实现思路及代码

    2018-04-05 08:32:34 次阅读 稿源:互联网
    广告

    Android模拟器内容是用OpenGL渲染的,所以用一般的编程截图(如PrintWindow()等)会是黑屏。这是因为画的东西放在framebuffer里。

    一种方法是通过adb把guest的framebuffer数据/dev/graphics/fb0倒到host,再转为图片。但这样速度比较慢。

    好在Android模拟器中把guest的framebuffer传到host进行显示,所以在host端只要将framebuffer输出到文件即可。

    首先定义每次framebuffer更新时的回调函数
    代码如下:

    void zjin_fb_update(void* context,
    int w, int h, int ydir,
    int format, int type,
    unsigned char* pixels)
    {
    #define CHANNEL 4
    BITMAPFILEHEADER bf;
    BITMAPINFOHEADER bi;
    int width = w;
    int height = h;
    FILE *file = fopen("capture.bmp", "wb");
    if( file!=NULL )
    {
    memset( &bf, 0, sizeof( bf ) );
    memset( &bi, 0, sizeof( bi ) );
    bf.bfType = 'MB';//BM?
    bf.bfSize = sizeof(bf)+sizeof(bi)+width*height*CHANNEL;
    bf.bfOffBits = sizeof(bf)+sizeof(bi);
    bi.biSize = sizeof(bi);
    bi.biWidth = width;
    bi.biHeight = height;
    bi.biPlanes = 1;
    bi.biBitCount = 8 * CHANNEL;
    bi.biSizeImage = width*height*CHANNEL;
    fwrite( &bf, sizeof(bf), 1, file );
    fwrite( &bi, sizeof(bi), 1, file );
    fwrite( pixels, sizeof(unsigned char), height*width*CHANNEL, file );
    fclose( file );
    }
    return;
    }

    然后把这个回调函数注册上去,比如在OpenGL窗口显示之后:
    代码如下:

    android_showOpenglesWindow(winhandle, drect.pos.x, drect.pos.y,
    drect.size.w, drect.size.h, disp->rotation * -90.);
    android_setPostCallback(zjin_fb_update, NULL);

    这样,每次有framebuffer的更新时,guest的屏幕都会存成一张bmp图片,这和用/dev/graphics/fb0的效果是一样的。

    注意用以上方法截下来的图和原图有两点不同,一是Blue和Red通道互换,这是因为framebuffer是RGB,bmp格式里是BGR。还有就是y轴的零点是左下角,这是由于framebuffer中是OpenGL的坐标系。也就是说,要得到原图还要经过RGB到BGR的转换和y-inversion。建议到处理图片时再做这些处理,一方面不会拖慢模拟器速度,另一方面像OpenCV里有现成的函数可供调用。

    一起学吧部分文章转载自互联网,供读者交流和学习,若有涉及作者版权等问题请及时与我们联系,以便更正、删除或按规定办理。感谢所有提供资讯的网站,欢迎各类媒体与一起学吧进行文章共享合作。

    广告
    广告
    广告