android截屏之方法
2013-10-15 10:25
337 查看
最近做项目需要一个功能——android截屏,对其进行了研究,整理如下:
一、基于view对象截图。
View类是一个超类,android中几乎所有可视的对象都继承与它。在实际应用中,只要获取到了你所要截图的View类或其子类的对象view,就可以通过函数Bitmap.createBitmap(view.getDrawingCache())来获取其截图。比如:我需要获取当前activity的截图,只需要先获取顶层view对象,在调用函数,其代码如下:
View v=this.getWindow().getDecorView();
Bitmap bitmap=Bitmap.createBitmap(v.getDrawingCache());
这样就获取了Bitmap对象,可以对其进行需要的操作,比如写入文件生成图片,或者写到网络输出流进行传输。
优点:速度快,代码简单。
缺点:1、不能全局截图。只能截取自己写的application中的屏幕,因为获取不到外部应用的view对象。
2、不能截图标题栏。这在某些需求中是不能被接受的。
二、通过adb进行截图。
豌豆荚以及一些宣传不需要ROOT截图的软件,都是采用这种方法来截图的。
这种方法的实质是读取android设备的帧缓存文件,一般是/dev/graphics/fb0文件,里面存储的是raw格式的像素数据。
通过android设备与pc相连,打开android设备的debug模式,adb可以读取到android上的任意文件,其中就包括了/dev/graphics/fb0。对其进行解析,转码,就可以生成截图。
优点:可以对android设备全局截图,且不需要root
缺点:需要连pc,需要开debug模式。汗啊!让用户开调试模式,不晕么。所以这种方式对于我们的应用一般不适合。
三、在android端读取帧缓存文件进行截图。这种方法的实用性最强,它唯一的缺点是需要root权限。目前我主要研究了以下三种方式的实现:
1、通过jni调用C来实现截图的功能。首先要编写好C的代码,调用相关的库来实现截图的功能,然后将其编译好,最后在android中导入库,并进行调用。过程比较长,代码就不贴了,具体可以google。
2、通过shell调用可执行的c程序来实现截图。在网上搜索到了gsnap这个东东,它最初是基于linux板子的截图,李先静先生对其进行了修改,使其可以支持android截图。
具体实现方法如下:
(1)获取gsnap文件,将其推送到设备的/data/data/工程名/app_bin中。在模拟器上运行时,可以直 接用adb进行push操作。发布程序的时候,最后将gsnap放到assets文件夹下,再通过代码将其推送到指定目录下,其代码见附录代码1。
(2)对gsnap文件修改权限,使其可以被程序访问。
命令:chmod 777 /data/data/工程名/app_bin/gsnap
(3)调用该文件。
命令:/data/data/工程名/app_bin/gsnap test.jpg /dev/graphics/fb0
其中(2)、(3)可通过附录代码2中的RunCommand函数实现。
3、通过android直接调用该帧缓存文件截图。这种方法的优点是省去了调用C的过程,而且代码相对更清晰,易于维护与优化。缺点是dalvik虚拟机性能不够好,而且当图片分辨率较大时,内存也不一定够用。其代码见附录代码3。
总结到此为止,欢迎交流。
附录:
代码1:
private void addGsnap()
{
File localFile = getDir(“bin”, 0);
String CFilePath = (localFile.getAbsolutePath() + “/gsnap”);
File file=new File(CFilePath);
if(!file.exists())
{
copyFile(“gsnap”,CFilePath);
}
}
public boolean copyFile(String from, String to) {
try {
int bytesum = 0;
int byteread = 0;
InputStream inStream = getResources().getAssets().open(from);
OutputStream fs = new BufferedOutputStream(new FileOutputStream(
to));
byte[] buffer = new byte[8192];
while ((byteread = inStream.read(buffer)) != -1) {
bytesum += byteread;
fs.write(buffer, 0, byteread);
}
inStream.close();
fs.close();
return true;
} catch (Exception e) {
System.out.println(e.getMessage());
return false;
}
}
代码2:
public static int RunCommand(String paramString)
{
int i = 0;
Process localProcess = null;
try
{
localProcess = Runtime.getRuntime().exec(“su”);
OutputStreamWriter localOutputStreamWriter = new OutputStreamWriter(localProcess.getOutputStream
(), “UTF-8″);
// localOutputStreamWriter.write(“export LD_LIBRARY_PATH=/vendor/lib:/system/lib\n”);
//localOutputStreamWriter.flush();
localOutputStreamWriter.write(paramString + “\n”);
localOutputStreamWriter.flush();
localOutputStreamWriter.write(“exit\n”);
localOutputStreamWriter.flush();
localOutputStreamWriter.close();
localProcess.waitFor();
int j = localProcess.exitValue();
if (j == 0)
i = 1;
try
{
localProcess.destroy();
return i;
}
catch (Exception localException4)
{
System.out.println(localException4.getMessage());
while (true)
localException4.printStackTrace();
}
}
catch (Exception localException2)
{
System.out.println(localException2.getMessage());
while (true)
{
localException2.printStackTrace();
try
{
localProcess.destroy();
}
catch (Exception localException3)
{
localException3.printStackTrace();
}
}
}
finally
{
}
}
代码3:
public Bitmap Shot(Service service)
{
long a0=System.currentTimeMillis();
InputStream stream =null;
DataInputStream dStream=null;
try
{
File file = new File(“/dev/graphics/fb0″);
stream = new FileInputStream(file);
dStream = new DataInputStream(stream);
}
catch(Exception e){System.out.println(e.getMessage());return;}
byte[] piex = new byte[height * width * deepth];
try
{
if(dStream.read(piex, 0, height * width * deepth) != -1)
{
long a2=System.currentTimeMillis();
System.out.println(“读取字节数组”+(a2-a1)+”毫秒”);
stream.close();
dStream.close();
int []colors = new int[height * width];
for(int m=0;m<piex.length;m++)
{
if(m%4 == 0)
{
int b = piex[m];
int g = piex[m+1];
int r = piex[m+2];
int a = piex[m+3];
colors[m/4]= (a << 24) + (r <<16) + (g <<8) + b;
}
}
Bitmap bitmap = Bitmap.createBitmap(colors,width, height, Bitmap.Config.ARGB_8888);
return bitmap;
}
}
}
一、基于view对象截图。
View类是一个超类,android中几乎所有可视的对象都继承与它。在实际应用中,只要获取到了你所要截图的View类或其子类的对象view,就可以通过函数Bitmap.createBitmap(view.getDrawingCache())来获取其截图。比如:我需要获取当前activity的截图,只需要先获取顶层view对象,在调用函数,其代码如下:
View v=this.getWindow().getDecorView();
Bitmap bitmap=Bitmap.createBitmap(v.getDrawingCache());
这样就获取了Bitmap对象,可以对其进行需要的操作,比如写入文件生成图片,或者写到网络输出流进行传输。
优点:速度快,代码简单。
缺点:1、不能全局截图。只能截取自己写的application中的屏幕,因为获取不到外部应用的view对象。
2、不能截图标题栏。这在某些需求中是不能被接受的。
二、通过adb进行截图。
豌豆荚以及一些宣传不需要ROOT截图的软件,都是采用这种方法来截图的。
这种方法的实质是读取android设备的帧缓存文件,一般是/dev/graphics/fb0文件,里面存储的是raw格式的像素数据。
通过android设备与pc相连,打开android设备的debug模式,adb可以读取到android上的任意文件,其中就包括了/dev/graphics/fb0。对其进行解析,转码,就可以生成截图。
优点:可以对android设备全局截图,且不需要root
缺点:需要连pc,需要开debug模式。汗啊!让用户开调试模式,不晕么。所以这种方式对于我们的应用一般不适合。
三、在android端读取帧缓存文件进行截图。这种方法的实用性最强,它唯一的缺点是需要root权限。目前我主要研究了以下三种方式的实现:
1、通过jni调用C来实现截图的功能。首先要编写好C的代码,调用相关的库来实现截图的功能,然后将其编译好,最后在android中导入库,并进行调用。过程比较长,代码就不贴了,具体可以google。
2、通过shell调用可执行的c程序来实现截图。在网上搜索到了gsnap这个东东,它最初是基于linux板子的截图,李先静先生对其进行了修改,使其可以支持android截图。
具体实现方法如下:
(1)获取gsnap文件,将其推送到设备的/data/data/工程名/app_bin中。在模拟器上运行时,可以直 接用adb进行push操作。发布程序的时候,最后将gsnap放到assets文件夹下,再通过代码将其推送到指定目录下,其代码见附录代码1。
(2)对gsnap文件修改权限,使其可以被程序访问。
命令:chmod 777 /data/data/工程名/app_bin/gsnap
(3)调用该文件。
命令:/data/data/工程名/app_bin/gsnap test.jpg /dev/graphics/fb0
其中(2)、(3)可通过附录代码2中的RunCommand函数实现。
3、通过android直接调用该帧缓存文件截图。这种方法的优点是省去了调用C的过程,而且代码相对更清晰,易于维护与优化。缺点是dalvik虚拟机性能不够好,而且当图片分辨率较大时,内存也不一定够用。其代码见附录代码3。
总结到此为止,欢迎交流。
附录:
代码1:
private void addGsnap()
{
File localFile = getDir(“bin”, 0);
String CFilePath = (localFile.getAbsolutePath() + “/gsnap”);
File file=new File(CFilePath);
if(!file.exists())
{
copyFile(“gsnap”,CFilePath);
}
}
public boolean copyFile(String from, String to) {
try {
int bytesum = 0;
int byteread = 0;
InputStream inStream = getResources().getAssets().open(from);
OutputStream fs = new BufferedOutputStream(new FileOutputStream(
to));
byte[] buffer = new byte[8192];
while ((byteread = inStream.read(buffer)) != -1) {
bytesum += byteread;
fs.write(buffer, 0, byteread);
}
inStream.close();
fs.close();
return true;
} catch (Exception e) {
System.out.println(e.getMessage());
return false;
}
}
代码2:
public static int RunCommand(String paramString)
{
int i = 0;
Process localProcess = null;
try
{
localProcess = Runtime.getRuntime().exec(“su”);
OutputStreamWriter localOutputStreamWriter = new OutputStreamWriter(localProcess.getOutputStream
(), “UTF-8″);
// localOutputStreamWriter.write(“export LD_LIBRARY_PATH=/vendor/lib:/system/lib\n”);
//localOutputStreamWriter.flush();
localOutputStreamWriter.write(paramString + “\n”);
localOutputStreamWriter.flush();
localOutputStreamWriter.write(“exit\n”);
localOutputStreamWriter.flush();
localOutputStreamWriter.close();
localProcess.waitFor();
int j = localProcess.exitValue();
if (j == 0)
i = 1;
try
{
localProcess.destroy();
return i;
}
catch (Exception localException4)
{
System.out.println(localException4.getMessage());
while (true)
localException4.printStackTrace();
}
}
catch (Exception localException2)
{
System.out.println(localException2.getMessage());
while (true)
{
localException2.printStackTrace();
try
{
localProcess.destroy();
}
catch (Exception localException3)
{
localException3.printStackTrace();
}
}
}
finally
{
}
}
代码3:
public Bitmap Shot(Service service)
{
long a0=System.currentTimeMillis();
InputStream stream =null;
DataInputStream dStream=null;
try
{
File file = new File(“/dev/graphics/fb0″);
stream = new FileInputStream(file);
dStream = new DataInputStream(stream);
}
catch(Exception e){System.out.println(e.getMessage());return;}
byte[] piex = new byte[height * width * deepth];
try
{
if(dStream.read(piex, 0, height * width * deepth) != -1)
{
long a2=System.currentTimeMillis();
System.out.println(“读取字节数组”+(a2-a1)+”毫秒”);
stream.close();
dStream.close();
int []colors = new int[height * width];
for(int m=0;m<piex.length;m++)
{
if(m%4 == 0)
{
int b = piex[m];
int g = piex[m+1];
int r = piex[m+2];
int a = piex[m+3];
colors[m/4]= (a << 24) + (r <<16) + (g <<8) + b;
}
}
Bitmap bitmap = Bitmap.createBitmap(colors,width, height, Bitmap.Config.ARGB_8888);
return bitmap;
}
}
}
相关文章推荐
- Android 下调试手机截屏的方法
- Android 屏幕截屏方法汇总
- Android截屏截图方法所有方法汇总(包括Activity、View、ScrollView、ListView、RecycleView、WebView截屏截图)
- android截屏代码实现方法
- android截屏方法
- android截屏代码实现方法
- android截屏代码实现方法
- Android截屏截图方法汇总(Activity、View、ScrollView、ListView、RecycleView、WebView截屏截图)
- Android禁止截屏的实现方法
- Android获取webView快照与屏幕截屏的方法
- Android截屏方法总结
- 几种Android截屏方法
- Android电视机截屏方法
- Android实现矩形区域截屏的方法
- android-------截屏的两种方法
- android uiautomator 一个截屏并且以当前时间命名图片名的方法
- android截屏的几种方法
- Android中实现矩形区域截屏方法步骤详解
- Android编程之截屏实现方法(包括scrollview与listview)
- android 和 ios 截屏 方法