展会信息港展会大全

编程实现Android模拟器中窗口截图存成文件
来源:互联网   发布日期:2016-01-14 15:01:17   浏览:1604次  

导读:android100-安卓软件开发网,全面的安卓软件开发教程,android开发永久免费在线学习资源,android学习网,手机软件开发,手机游戏开发,android开发教程,安卓应用开发。...

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

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

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

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

[cpp]

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;

}

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窗口显示之后:

[cpp]

android_showOpenglesWindow(winhandle, drect.pos.x, drect.pos.y,

drect.size.w, drect.size.h, disp->rotation * -90.);

android_setPostCallback(zjin_fb_update, NULL);

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里有现成的函数可供调用。

赞助本站

人工智能实验室

相关热词: android开发 教程

AiLab云推荐
展开

热门栏目HotCates

Copyright © 2010-2024 AiLab Team. 人工智能实验室 版权所有    关于我们 | 联系我们 | 广告服务 | 公司动态 | 免责声明 | 隐私条款 | 工作机会 | 展会港