源码网商城,靠谱的源码在线交易网站 我的订单 购物车 帮助

源码网商城

详解有关Android截图与录屏功能的学习

  • 时间:2022-07-24 13:42 编辑: 来源: 阅读:
  • 扫一扫,手机访问
摘要:详解有关Android截图与录屏功能的学习
简单的截屏和录屏功能。 因为MediaProjection是5.0以上才出现的,所以今天所讲述功能实现,只在5.0以上的系统有效。 [b]截屏:[/b] [b]步骤如下:[/b] 1:获取MediaProjectionManager 2:通过MediaProjectionManager.createScreenCaptureIntent()获取Intent 3:通过startActivityForResult传入Intent然后在onActivityResult中通过MediaProjectionManager.getMediaProjection(resultCode,data)获取MediaProjection 4:创建ImageReader,构建VirtualDisplay 5:最后就是通过ImageReader截图,就可以从ImageReader里获得Image对象。 6:将Image对象转换成bitmap [b]实现:[/b] 步骤已经给出了,我们就按照步骤来实现代码吧。 首先MediaProjectionManager是系统服务,我们通过getSystemService(MEDIA_PROJECTION_SERVICE)获取它
[url=https://developer.android.google.cn/reference/android/graphics/ImageFormat.html]ImageFormat[/url]或[url=https://developer.android.google.cn/reference/android/graphics/PixelFormat.html]PixelFormat[/url]中的一个,这两个Format里有很多格式,大家可以点进去看看,我们例子中使用的是PixelFormat.RGBA_8888格式(需要注意的是并不是所有的格式都被ImageReader支持,比如说ImageFormat.NV21)。 第四个参数是maxImages,这个参数指的是你想同时在ImageReader里获取到的Image对象的个数,这个参数我不是很懂,我不理解同时的意思。我的理解是ImageReader是一个类似数组的东西,然后我们可以通过acquireLatestImage()或acquireNextImage()方法来得到里面的Image对象(可能有误,仅供参考)。这个值应该设置的越小越好,但是得大于0,所以我们上面设置的是1。 [b]然后我们看看mediaProjection.createVirtualDisplay方法:[/b]
createVirtualDisplay(@NonNull String name,
      int width, int height, int dpi, int flags, @Nullable Surface surface,
      @Nullable VirtualDisplay.Callback callback, @Nullable Handler handler)
首先这个方法返回的是VirtualDisplay。 前四个不用说了,分别是VirtualDisplay的名字,宽,高和dpi。 第五个参数,大家可以点 [url=https://developer.android.google.cn/reference/android/hardware/display/DisplayManager.html]DisplayManager[/url]查看所有的flags,我没有具体的研究过,在本次要实现的例子里,除了VIRTUAL_DISPLAY_FLAG_SECURE这个会报错,其他的flags效果都一样。 第六个参数,是一个Surface。我这里表达一下我的理解,当VirtualDisplay被创建出来时,也就是createVirtualDisplay调用后,你在真实屏幕上的每一帧都会输入到Surface参数里。也就是说,如果你放个SurfaceView,然后传入SurfaceView的Surface那么你在屏幕上的操作都会显示在SurfaceView里(这里我们后面录屏会讲)。我们这里传入的是ImageReader的Surface。这其中的逻辑我的理解是这样的,真实屏幕的每一帧都都会传给ImageReader,根据ImageReader的maxImages参数,比如说maxImages是2,那么ImageReader始终保持两帧图片,但这两帧图片是一直随着真实屏幕的操作而更新的(不知道大家有没有听懂)。 第七个参数,是一个回调函数,在VirtualDisplay状态改变时调用。因为我们这里没有,所以传null。 第八个参数,这里我给出原文:“The Handler on which the callback should be invoked, or null if the callback should be invoked on the calling thread's main Looper.”因为我翻译不好。不过和普通的Handler使用场景类似。 现在我们ImageReader和VirtualDisplay,接下来我们就可以通过ImageReader的acquireLatestImage()或acquireNextImage()来得到Image对象了。
SystemClock.sleep(1000);
Image image = imageReader.acquireNextImage();
这里有个坑,就是你在获取Image的时候,得先暂停1秒左右,不然就会获取失败(原因未知)。 现在我们有了Image对象,但是Image对象并不能直接作为UI资源被使用,我们可以将它转换成Bitmap对象。
    int width = image.getWidth();
    int height = 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 * width;
    bitmap = Bitmap.createBitmap(width + rowPadding / pixelStride, height, Bitmap.Config.ARGB_8888);
    bitmap.copyPixelsFromBuffer(buffer);
    image.close();
这里最主要的逻辑就是像素与字节的转换,我们需要将Image对象的字节流写进Bitmap里,但是Bitmap接收的是像素格式的。 我们一行一行来看: 首先获取image对象的宽和高,注意width和height是像素格式的。 然后获取ByteBuffer,里面存放的就是图片的字节流,是字节格式的。我是这么理解的,ByteBuffer里面是一长串的字节序列,按照某种格式分成行列就变成了图片。 然后获取PixelStride,这指的是两个像素的距离(就是一个像素头部到相邻像素的头部),这是字节格式的。 RowStride是一行占用的距离(就是一行像素头部到相邻行像素的头部),这个大小和width有关,这里需要注意,因为内存对齐的原因,所以每行会有一些空余。这个值也是字节格式的。 紧接着我们需要创建一个Bitmap用来接受Image的buffer的输入,buffer是字节流,它会按照我们设置的format转换成像素,所以这里最重要的一个地方就是Bitmap创建的大小,因为高度就是行数所以就是height,但是宽度因为上面说的内存对齐问题会有些空余,所以我们要先求出空余部分,然后加上width。
int rowPadding = rowStride - pixelStride * width;
这句话用整行的距离减去了一行里像素及空隙占用的距离,剩下的就是空余部分。但是这个是字节格式的。我们将它除以pixelStride,也就是一个像素及空隙占用的字节大小,就转换成了像素格式。 然后:
width + rowPadding / pixelStride
这个就是一行里像素的占用了,我们将它传给Bitmap:
[url=https://github.com/yrom/ScreenRecorder]ScreenRecorder[/url] 本篇博客的实例代码: github项目地址:[url=https://github.com/ChenTianSaber/ScreenRecorderShoter]https://github.com/ChenTianSaber/ScreenRecorderShoter[/url] 源码下载地址:[url=http://xiazai.jb51.net/201704/yuanma/ScreenRecorderShoter_jb51.rar]ScreenRecorderShoter_jb51.rar[/url] 以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程素材网。
  • 全部评论(0)
联系客服
客服电话:
400-000-3129
微信版

扫一扫进微信版
返回顶部