关于安卓SurfaceView截屏
2015.12.9号是一个值得记得日子,开始拖着背包从学校出来,挤上火车,做着接近30小时的硬座,来到了美丽的成都,那时候赵雷的<成都>还没火,‘走到玉林路的尽头 坐在小酒馆的门口 ‘,多么诗情画意的生活啊。来不及享受这安逸之都的生活,便匆匆的开始实习生涯。
时至今日,也已经毕业大半年了,也从实习生正式成了职场人。身边大神很多,公司也是藏龙卧虎,也感觉应该养成写作的习惯,一来可以总结一下,以便之后自己查看。同时,因为写作也会去查很多资料,也可以加深对问题的认识。最后,只是也是一种分享的过程,网上东西良莠不齐,能够对一些自己熟悉的领域写好,帮助别人也是一种快乐吧。总不至于自己每天在各种bug中享受暗无天日的生活吧,一度开始怀疑人生。找点有意义的事情做,总是好的。
下面来谈谈SurfaceView截屏的问题,SufaceView视图原理我就不再赘述,网上一搜大把,下面直接将贴代码吧。
1.root情况下,读取Framebuff上面的像素,通过像素得到Bitmap,再将Bitmap以图片形式输出。
private static final String DEVICE_NAME = "/dev/graphics/fb0";
@SuppressWarnings("deprecation")
public static Bitmap acquireScreenshot(Context context) {
WindowManager mWinManager = (WindowManager) context
.getSystemService(Context.WINDOW_SERVICE);
DisplayMetrics metrics = new DisplayMetrics();
Display display = mWinManager.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[] arrayOfByte = new byte[height * width * deepth];
try {
// 读取设备缓存,获取屏幕图像流
InputStream localInputStream = readAsRoot();
DataInputStream localDataInputStream = new DataInputStream(
localInputStream);
localDataInputStream.readFully(arrayOfByte);
localInputStream.close();
int[] tmpColor = new int[width * height];
int r, g, b;
for (int j = 0; j < width * height * deepth; j += deepth) {
b = arrayOfByte[j] & 0xff;
g = arrayOfByte[j + 1] & 0xff;
r = arrayOfByte[j + 2] & 0xff;
tmpColor[j / deepth] = (r << 16) | (g << 8) | b | (0xff000000);
}
// 构建bitmap
Bitmap scrBitmap = Bitmap.createBitmap(tmpColor, width, height,
Bitmap.Config.ARGB_8888);
return scrBitmap;
} catch (Exception e) {
Log.d(TAG, "#### 读取屏幕截图失败");
e.printStackTrace();
}
return null;
}
/**
* @Title: readAsRoot
* @Description: 以root权限读取屏幕截图
* @throws Exception
* @throws
*/
public static InputStream readAsRoot() throws Exception {
File deviceFile = new File(DEVICE_NAME);
Process localProcess = Runtime.getRuntime().exec("su");
String str = "cat " + deviceFile.getAbsolutePath() + "\n";
localProcess.getOutputStream().write(str.getBytes());
return localProcess.getInputStream();
}
//将读取的bitmap输出图片到SD卡上
public static void shoot(Activity activity, File filePath) {
if (filePath == null) {
return;
}
if (!filePath.getParentFile().exists()) {
filePath.getParentFile().mkdirs();
}
FileOutputStream fos = null;
try {
fos = new FileOutputStream(filePath);
if (null != fos) {
takeScreenShot(activity).compress(Bitmap.CompressFormat.PNG, 100, fos);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
if (fos != null) {
try {
fos.flush();
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
2.非root 直接在SurfaceView中实时输出bitmap,然后将bitmap输出成图片保存下来。
/**
* 将实时bitmap输出到指定sd卡。
*/
public void saveScreenshot() {
if (ensureSDCardAccess()) {
Bitmap bitmap = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
doDraw(1, canvas);
File file = new File(mScreenshotPath + "/" + System.currentTimeMillis() + ".jpg");
FileOutputStream fos;
try {
fos = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
fos.close();
} catch (FileNotFoundException e) {
Log.e("xxx", "FileNotFoundException", e);
} catch (IOException e) {
Log.e("xxx", "IOEception", e);
}
}
}
/**
*
* 指定路径文件是否存在
*/
private boolean ensureSDCardAccess() {
File file = new File(mScreenshotPath);
if (file.exists()) {
return true;
} else if (file.mkdirs()) {
return true;
}
return false;
}
二.附上普通view截图方式。
public class ScreenShot {
public static void shoot(Activity activity, File filePath) {
if (filePath == null) {
return;
}
if (!filePath.getParentFile().exists()) {
filePath.getParentFile().mkdirs();
}
FileOutputStream fos = null;
try {
fos = new FileOutputStream(filePath);
if (null != fos) {
takeScreenShot(activity).compress(Bitmap.CompressFormat.PNG, 100, fos);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
if (fos != null) {
try {
fos.flush();
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
@SuppressWarnings("deprecation")
private static Bitmap takeScreenShot(Activity activity) {
View view = activity.getWindow().getDecorView();
view.setDrawingCacheEnabled(true);
view.buildDrawingCache();
Bitmap bitmap = view.getDrawingCache();
Rect frame = new Rect();
activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(frame);
int statusBarHeight = frame.top;
int width = activity.getWindowManager().getDefaultDisplay().getWidth();
int height = activity.getWindowManager().getDefaultDisplay()
.getHeight();
//
Bitmap b = Bitmap.createBitmap(bitmap, 0, statusBarHeight, width,
height - statusBarHeight);
view.destroyDrawingCache();
return b;
}
}