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

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

时间: 2024-10-26 10:31:38

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

android studio-如何将Android Studio 中的项目打包成jar文件,求方法

问题描述 如何将Android Studio 中的项目打包成jar文件,求方法 如题,求能用的方法,试了好多百度的方法,不怎么好用啊,越详细越好 解决方案 AS 生成Jar包 在Gradle中添加任务声明 def makeJar(String target, String classDir) { exec { executable "jar" //调用jar args "cvf", target args "-C", classDir args

在android模拟器中解析不到tomcat中的xml文件,

问题描述 在android模拟器中解析不到tomcat中的xml文件, 在android模拟器中解析不到tomcat中的xml文件,但是在浏览器中使用相同的地址,却可以访问 package xtm.mp3player; import xtm.download.HttpDownloader; import android.app.ListActivity; import android.os.Bundle; import android.util.Log; import android.view.

使用adb命令向Android模拟器中导入通讯录联系人的方法_Android

本文实例讲述了使用adb命令向Android模拟器中导入通讯录联系人的方法.分享给大家供大家参考.具体实现方法如下: 使用adb提供的命令, 可以非常方便地从PC中将通讯录导入android模拟器中. 首先要先准备好固定格式的contacts.vcf文件, 该文件即android中的通讯录存储文件. 格式如下: 复制代码 代码如下: BEGIN:VCARD  VERSION:3.0  N:15200000000;;;;  TEL;TYPE=cell:15200000000  END:VCARD 

Android模拟器中安装apk的方法_Android

本文讲述了Android模拟器中安装apk的方法.分享给大家供大家参考,具体如下: 第一步: 在Eclipse中启动模拟器. 第二步: 打开doc命名窗口,转到你android sdk安装目录中的platform-tools下, 如我的是 E:/Program Files/andriod_sdk/platform-tools 第三步: 利用adb来对android进行安装操作.建议第三步使用方案一 方案一: 为了方便,我们应将要安装的apk直接拷到platform-tools所在的目录下,然后在

使用adb命令向Android模拟器中导入通讯录联系人的方法

本文实例讲述了使用adb命令向Android模拟器中导入通讯录联系人的方法.分享给大家供大家参考.具体实现方法如下: 使用adb提供的命令, 可以非常方便地从PC中将通讯录导入android模拟器中. 首先要先准备好固定格式的contacts.vcf文件, 该文件即android中的通讯录存储文件. 格式如下: 复制代码 代码如下:BEGIN:VCARD  VERSION:3.0  N:15200000000;;;;  TEL;TYPE=cell:15200000000  END:VCARD 

手机开发-Android 模拟器中按菜单Menu键弹出菜单项MenuItem,点击菜单项中的菜单项没反应!!!

问题描述 Android 模拟器中按菜单Menu键弹出菜单项MenuItem,点击菜单项中的菜单项没反应!!! public boolean onCreateOptionsMenu(Menu menu){ getMenuInflater().inflate(R.menu.main,menu); return true; } public boolean onOptionsItemSeleted(MenuItem item){ switch(item.getItemId()) { case R.i

Android中把bitmap存成BMP格式图片的方法

最近的项目,做图片的另存为功能,需要把图片存成jpg,png,bmp.对于jpg和png来说相对简单,android提供了bitmap.compress()方法可以马上解决.但是对于BMP这种格式,没有很好的支持.我花了几天时间在网上找了很久,都没有找到有用的答案,同样也发了疑问,没有合适的解答. package com.test.bitmap; import java.io.FileNotFoundException; import java.io.FileOutputStream; impo

在Android模拟器中使用SDCard

数据存储的一个方式是将数据存储到SDCard中,在模拟器中要使用SDCard,步骤如下: 1.用cmd中进入到android的SDK的platform-tools目录下,执行mksdcard创建. D:\android-sdk-windows\platform-tools>mksdcard 1024M D:\sdcard.img 这样就在D盘下创建了一个1024M的SDCard. 2.关联镜像文件到Eclipse. 在Eclipse中,运行Run->Run Configuration->

linux中vmstat操作记录保存成文件

  vmstat 命令报告关于内核线程.虚拟内存.磁盘.陷阱和 CPU 活动的统计信息.由 vmstat 命令生成的报告可以用于平衡系统负载活动.系统范围内的这些统计信息(所有的处理器中)都计算出以百分比表示的平均值,或者计算其总和. 遇到个问题.机器在晚上的运行情况需要监控下.采用vmsata将日志保存成文件.第二天来看. 方法 vmstat 60 >a.log 缺点:无法显示每条记录的具体时间. 解决方法.写另外一个脚本 定时往a.log文件中写入时间 脚本如下 a.sh while : d