Android实现全局截图以及录屏
来源:互联网 发布:薛之谦的淘宝店经验 编辑:程序博客网 时间:2024/05/17 13:07
废话不多说 直接上代码(使用kotlin编写大致与java差不多) 代码注释也挺详细的
利用mediaProjection 实现截屏与录屏
mediaProjection 是android 5.0 加入的一个 主要用户捕捉屏幕的东西
createVirtualDisplay(String name, int width, int height, int dpi, int flags, Surface surface, VirtualDisplay.Callback callback, Handler handler)//创建一个VirtualDisplay捕获屏幕的内容。//捕捉到的内容将写入到传入的surface中//因此可将传入MediaRecorder以及ImageReader中的surface 并 通过他们取出surface进行截图与录制
class ScreenCapture constructor(private val width : Int ,private val height : Int ){ private var mImageReader : ImageReader = ImageReader.newInstance(width,height, PixelFormat.RGBA_8888,3) private var mediaProjectionManager = App.app.mediaProjectionManager //初始化截图功能 fun startCapture(resultCode : Int, data : Intent?) { val mediaProjection = mediaProjectionManager.getMediaProjection(resultCode, data) mediaProjection.createVirtualDisplay("capture",width,height,1, DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC, mImageReader.surface,null,null) } fun acquire() : Bitmap?{ var image: Image? = null //当未开始录制的时候先调用此方法会报错 //java.lang.IllegalStateException: mImageReader.acquireLatestImage() must not be null try { image = mImageReader.acquireLatestImage() //此高度和宽度似乎与ImageReader构造方法中的高和宽一致 val iWidth = image.width val iHeight = image.height //panles的数量与图片的格式有关 val plane = image.planes[0] val bytebuffer = plane.buffer //计算偏移量 val pixelStride = plane.pixelStride val rowStride = plane.rowStride; val rowPadding = rowStride - pixelStride * iWidth; val bitmap = Bitmap.createBitmap(iWidth + rowPadding / pixelStride, iHeight, Bitmap.Config.ARGB_8888); bitmap.copyPixelsFromBuffer(bytebuffer) //必须要有这一步,不如图片会有黑边 return Bitmap.createBitmap(bitmap,0,0,iWidth,iHeight) }catch (e : Exception){ e.printStackTrace() return null }finally { image?.close() } }}
class MainActivity : PermissionCompatActivity(), MainContract.View { //截屏图片大小设置 val width = 1440 val height = 2560 var capturor: ScreenCapture = ScreenCapture(width, height) override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) //启动MediaProjection并准备截图 startActivityForResult(mediaProjectionManager.createScreenCaptureIntent(), 1) imageView.setOnClickListener { imageView.setImageBitmap(capturor.acquire()) } } override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { //截屏前的准备 capturor.startCapture(resultCode,data) }}
拼命截图放入同一个ImageView中的结果
屏幕录制需要的权限
Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.RECORD_AUDIO
class ScreenRecorder(private val width: Int, private val height: Int, val outputFile: String) { private val mRecorder = MediaRecorder() private val mediaProjectionManager = App.app.mediaProjectionManager //初始化Recorder init { prepare() } private fun prepare() { with(mRecorder) { setAudioSource(MediaRecorder.AudioSource.MIC) setVideoSource(MediaRecorder.VideoSource.SURFACE) setOutputFormat(MediaRecorder.OutputFormat.MPEG_4) setVideoEncoder(MediaRecorder.VideoEncoder.H264) setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB) //帧率 帧数简单地说,帧数就是在1秒钟时间里传输的图片的帧数, // 也可以理解为图形处理器每秒钟能够刷新几次,通常用fps(Frames Per Second)表示。 setVideoFrameRate(30) //码率 码率:影响体积,与体积成正比:码率越大,体积越大;码率越小,体积越小。 //码率就是数据传输时单位时间传送的数据位数,一般我们用的单位是kbps即千位每秒。也就是取样率 setVideoEncodingBitRate(500 * 1000) setOutputFile(outputFile) //设置输出目录 val display = App.app.windowManager.defaultDisplay val dm = DisplayMetrics() display.getMetrics(dm) setVideoSize(width, height) prepare() } } fun startRecord(resultCode: Int, data: Intent?) { val mediaProjection = mediaProjectionManager.getMediaProjection(resultCode, data) ?: return //如果无法获取mediaProjection 则返回 mediaProjection.createVirtualDisplay("test", width, height, 1, DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR, mRecorder.surface, null, null) mRecorder.start() } fun stopRecord() { Thread { //避免录制时间过短而报错 Thread.sleep(1000) mRecorder.stop() }.start() }}
class MainActivity : PermissionCompatActivity(), MainContract.View { val width = 1440 val height = 2560 val mRecorder = ScreenRecorder(width, height, outputFile = Environment.getExternalStorageDirectory().path + "/output.mp4") override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) //开始的同时开始录制 startActivityForResult(mediaProjectionManager.createScreenCaptureIntent(), 1) imageView.setOnClickListener { mRecorder.stopRecord() } } override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { //开始录制 mRecorder.startRecord(resultCode,data) }}
阅读全文
0 0
- Android实现全局截图以及录屏
- Android 录屏\截图
- Android录屏与截图功能
- Android Multimedia实战(四)MediaProjection实现截图,与MediaMuxer实现录屏为MP4,Gif格式
- Android MediaProjection截屏与录屏(surfaceview截图)
- Android开发笔记(一百三十)截图和录屏
- 有关Android截图与录屏功能的学习
- 有关Android截图与录屏功能的学习
- MediaProjection实现截图,与MediaMuxer实现录屏为MP4,Gif格式
- Android录屏功能的实现
- android 调用 screenrecord 实现录屏
- Android录屏功能的实现
- android 5.0+录屏功能实现
- Android实现内录
- Android截图代码实现
- Android 截图实现(2)
- Android截图代码实现
- Android屏幕截图实现
- Java ConcurrentModificationException异常原因和解决方法 目录 一.ConcurrentM
- 什么是态势感知?
- Kotlin 设计模式-装饰器
- 关于filter的配置
- CONTAINING_RECORD 宏
- Android实现全局截图以及录屏
- 请求图灵的简单方法,子线程方法放到主线程执行 runOnUiThread
- bzoj1057 [ZJOI2007]棋盘制作
- Android键盘输入法(一)——键盘类型
- React Native 使用try catch解决TextInput输入的时候中文状态下崩溃的原因
- 软件工程师
- 上传文件
- [LearningPython]python学习笔记
- 音乐、编程、人生