今天需要写一个工具类,需要将签名的图案画生成一张图片,百度了一下Android截屏,发现 非常简单的一句代码就能实现:
View..getDrawingCache()就能得到一个Bitmap,然后将这个Bitmap生成一张图片即可,但是在实际运用当中发现一个问题,就是该方法返回的Bitmap为空,后来继续百度,发现了比较好的方法:
http://my.oschina.net/u/816576/blog/345761《Android新姿势:截屏代码整理》提供了三套方法:
第一种是将直接从提供的View里面去截屏,拿到画面OK;如果没有设置图片背景颜色的话,那么图片是完全透明的,所以查看图片的时候如果手机黑屏的话,可以用不同设备查看一下:
该方法比较可靠,图片尺寸可控(自定义View,大小自己定义),背景透明(如果不喜欢,你也可以自己增加一个背景色)最后他调用也相当方便!
Bitmap bitmap = getViewBitmap(selfView);//获取Bitmap
saveMyBitmap(bitmap, "gg");//保存到本地,图片名称为“gg”
源码:
/**
* 指定控件内容截屏
* @param View
* @return Bitmap
*/
public static Bitmap getViewBitmap(View v) {
v.clearFocus(); //
v.setPressed(false); //
// 能画缓存就返回false
boolean willNotCache = v.willNotCacheDrawing();
v.setWillNotCacheDrawing(false);
int color = v.getDrawingCacheBackgroundColor();
v.setDrawingCacheBackgroundColor(0);
if (color != 0) {
v.destroyDrawingCache();
}
v.buildDrawingCache();
Bitmap cacheBitmap = v.getDrawingCache();
if (cacheBitmap == null) {
return null;
}
Bitmap bitmap = Bitmap.createBitmap(cacheBitmap);
// Restore the view
v.destroyDrawingCache();
v.setWillNotCacheDrawing(willNotCache);
v.setDrawingCacheBackgroundColor(color);
return bitmap;
}
第二种方法实际上是对Activity进行截屏,同上类似,但是我们一般需要的图片内容都用不到这么大,后期还需要进行图片加工,比较不方便。源码如下:
public static Bitmap captureScreen(Activity activity) {
activity.getWindow().getDecorView().setDrawingCacheEnabled(true);
Bitmap bmp = activity.getWindow().getDecorView().getDrawingCache();
return bmp;
}
第三种方法也管用,是第二种方法的升级,而且还需要root权限才可以,源码如下:
/**
* 截屏
* @param activity
* @return Bitmap
*/
public static Bitmap captureScreen(Activity activity) {
// 获取屏幕大小:
DisplayMetrics metrics = new DisplayMetrics();
WindowManager WM = (WindowManager) activity
.getSystemService(Context.WINDOW_SERVICE);
Display display = WM.getDefaultDisplay();
display.getMetrics(metrics);
int height = metrics.heightPixels; // 屏幕高
int width = metrics.widthPixels; // 屏幕的宽
// 获取显示方式
int pixelformat = display.getPixelFormat();
PixelFormat localPixelFormat1 = new PixelFormat();
PixelFormat.getPixelFormatInfo(pixelformat, localPixelFormat1);
int deepth = localPixelFormat1.bytesPerPixel;// 位深
byte[] piex = new byte[height * width * deepth];
try {
Runtime.getRuntime().exec(
new String[] { "/system/bin/su", "-c",
"chmod 777 /dev/graphics/fb0" });
} catch (IOException e) {
e.printStackTrace();
}
try {
// 获取fb0数据输入流
InputStream stream = new FileInputStream(new File(
"/dev/graphics/fb0"));
DataInputStream dStream = new DataInputStream(stream);
dStream.readFully(piex);
} catch (Exception e) {
e.printStackTrace();
}
// 保存图片
int[] colors = new int[height * width];
for (int m = 0; m < colors.length; m++) {
int r = (piex[m * 4] & 0xFF);
int g = (piex[m * 4 + 1] & 0xFF);
int b = (piex[m * 4 + 2] & 0xFF);
int a = (piex[m * 4 + 3] & 0xFF);
colors[m] = (a << 24) + (r << 16) + (g << 8) + b;
}
// piex生成Bitmap
Bitmap bitmap = Bitmap.createBitmap(colors, width, height,
Bitmap.Config.ARGB_8888);
return bitmap;
}
最后,保存图片的时候不要忘记添加权限:<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_FRAME_BUFFER" />
最最后,保存到本地的时候,注意path一定是已经建立好的,即父级目录存在,否则本地保存注定失败,源码:/**
* 将bitmap保存为指定名称图片
* @param mBitmap
* @param bitName
*/
public void saveMyBitmap(Bitmap mBitmap,String bitName) {
Log.i("tarena", "saveMyBitmap");
File f = new File( "/sdcard/"+bitName + ".jpg");
Log.i("tarena", "new File");
try {
FileOutputStream fOut = new FileOutputStream(f);
boolean it = (mBitmap!=null);
Log.i("tarena", "Bitmap不为空:"+it);
boolean that = (fOut!=null);
Log.i("tarena", "fOut不为空:"+that);
mBitmap.compress(Bitmap.CompressFormat.PNG, 100, fOut);
Log.i("tarena", "图片保存成功");
fOut.flush();
fOut.close();
} catch (Exception e) {
e.printStackTrace();
Log.i("tarena", "err!!!!!!!!!!!!!!!!!!!!!!!!!");
}
}