Android 5.0 以上系统提供了MediaProjection。可以利用截取录制屏幕!
关键字:MediaProhectionManager, MediaProjection, ImageReader, VirtualDisplay
MediaProhection 使用时首先需要通过Activity申请权限。
startActivityForResult(
(MediaProjectionManager) getSystemService(Context.MEDIA_PROJECTION_SERVICE).
createScreenCaptureIntent(),
1);
onActivityResult()方法中获取到授权成功及创建MediaProjection需要的Intent数据,如果不希望在onActivityResult中直接创建MediaProjection对象,那么需要将该Intent保存起来。
mMediaProjection = mediaProjectionManager.getMediaProjection(Activity.RESULT_OK, intentData);
创建ImageReader用于截取数据
mImageReader = ImageReader.newInstance(mScreenWidth, mScreenHeight, PixelFormat.RGBA_8888, 1);
注意,图片Format只能是PixelFormat.RGBA_8888,使用其他无法对应截屏数据,会发生异常。
ImageReader设置OnImageAvailableListener回调
ImageReader.OnImageAvailableListener onImageAvailableListener = new ImageReader.OnImageAvailableListener() {
@Override
public void onImageAvailable(ImageReader reader) {
Image image = reader.acquireLatestImage();
if(null != image) {
image.close();
}
}
};
m
创建VirtualDisplay虚拟现实对象
mVirtualDisplay = mMediaProjection.createVirtualDisplay("mirror_virtual_diaplay",
mScreenWidth,
mScreenHeight, mDensityDpi,
DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR,
mImageReader.getSurface(), null, null);
Image数据解析
public void getBitmapFromImage(Image image) {
final int imageWidth = image.getWidth();
final int imageHeight = image.getHeight();
final Image.Plane[] planes = image.getPlanes();
final ByteBuffer buffer = planes[0].getBuffer();
int pixelStride = planes[0].getPixelStride();
int rowStride = planes[0].getRowStride();
int rowPadding = rowStride - pixelStride * imageWidth;
final Bitmap bitmap = Bitmap.createBitmap(imageWidth + rowPadding / pixelStride, imageHeight, Bitmap.Config.ARGB_8888);
bitmap.copyPixelsFromBuffer(buffer);
}
总结及问题点:有些时候截取数据与实际观察数据不符,因为截取内容包含透明度,需要以实际情况为准!颜色叠加可参考如下公式:
/* 透明度颜色与背景颜色叠加算法 */
/* C = C0*(1-a1) + C1*a1 */
/* 多透明色克叠加使用。 */
首先要确定底色色值C,叠加颜色C0及叠加颜色透明度a1。多颜色叠加可嵌套使用。
VirtualDisplay创建宽高比如果与屏幕比例不一致,会出现黑色边框。