一、前言
从Camera1到Camera2,再到现在的Jetpack中的CameraX,Google一直在致力于让AndroID应用开发者更加方便的去使用摄像头相关的API,更加简单快速的实现摄像头相关的应用功能;下面就来学习一下使用CameraX实现拍照和录制视频功能;
二、CameraX概述
CameraX是AndroID Jetpack中的组件,旨在简化相机相关的应用开发工作,但是要注意的是CameraX向下最低兼容到AndroID 5.0(API 21);CameraX利用了Camera2的功能,但采取了一种具有生命周期感知能力且基于用例(UseCase)的更简单的方式,它还解决了设备兼容性问题。
三、CameraX使用
添加依赖:
在Module的build.gradle中添加CameraX相关的依赖
dependencIEs { ..... def camerax_version = "1.0.0-beta07" // CameraX core library using camera2 implementation implementation "androIDx.camera:camera-camera2:$camerax_version" // CameraX lifecycle library implementation "androIDx.camera:camera-lifecycle:$camerax_version" // CameraX VIEw class implementation "androIDx.camera:camera-vIEw:1.0.0-Alpha14"}
同时CameraX需要一些属于java8的方法,因此我们需要相应地设置编译选项。在build.gradle文件中androID块的末尾,buildTypes之后,添加以下内容:
androID { ... compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } }
添加相关权限
添加相机权限,这里因为我们还要实现照片拍摄,视频录制所以除了相机权限,还需要录音权限,以及存储的读写权限;
<uses-feature androID:name="androID.harDWare.camera.any" /> <uses-permission androID:name="androID.permission.RECORD_AUdio" /> <uses-permission androID:name="androID.permission.CAMERA" /> <uses-permission androID:name="androID.permission.READ_EXTERNAL_STORAGE"/> <uses-permission androID:name="androID.permission.WRITE_EXTERNAL_STORAGE"/>
相机预览
相机预览我们肯定是要有一个显示摄像头画面的VIEw,在使用Camera1或Camera2时我们一般都是使用SurfaceVIEw来显示摄像头画面,CameraX中提供PrevIEwVIEw
作为显示摄像头画面的VIEw
所以我么在布局中添加一个PrevIEwVIEw
<FrameLayout xmlns:androID="http://schemas.androID.com/apk/res/androID" androID:layout_wIDth="match_parent" androID:layout_height="match_parent"> <androIDx.camera.vIEw.PrevIEwVIEw androID:ID="@+ID/prevIEw_activity_vIDeo_recode" androID:layout_wIDth="match_parent" androID:layout_height="match_parent" /></FrameLayout>
并且使用PrevIEw相关的API实现摄像头画面的预览
@Suppresslint("RestrictedAPI") private voID prevIEw() { ListenableFuture<ProcessCameraProvIDer> ListenableFuture = ProcessCameraProvIDer.getInstance(mActivity); try { mProcessCameraProvIDer = ListenableFuture.get(); mProcessCameraProvIDer = ListenableFuture.get(); mPrevIEw = new PrevIEw.Builder() .setTargetResolution(new Size(640, 480)) .build(); mPrevIEw.setSurfaceProvIDer(mPrevIEwVIEw.createSurfaceProvIDer()); ImageAnalysis imageAnalysis = new ImageAnalysis.Builder() .build(); imageAnalysis .setAnalyzer(ContextCompat.getMainExecutor(mActivity), new ImageAnalysis.Analyzer() { @OverrIDe public voID analyze(@NonNull ImageProxy image) { Log.e(TAG, "analyze: " + image); image.close(); } } ); mProcessCameraProvIDer.bindTolifecycle((lifecycleOwner) mActivity, CameraSelector.DEFAulT_BACK_CAMERA, mPrevIEw, imageAnalysis ); } catch (Exception e) { e.printstacktrace(); } }
我们这里在实现摄像头画面预览的同时,还添加了一ImageAnalysis 图像分析用例,ImageAnalysis设置一个ImageAnalysis.Analyzer分析器,这个用例是用来实现每一帧画面的数据分析的,每一帧画面都会回调到analyze(ImageProxy image)方法
我们可以从IamgeProxy中拿到每一帧画面的图像数据;
这里要注意在回调方法中使用完IamgeProxy后,一定要调用IamgeProxy.close()方法关闭,否则analyze(ImageProxy image)这个方法只会回调一次,这是个坑一定要注意关闭;
拍摄照片
使用IamgeCapture相关的API实现照片拍摄功能
private voID takePhoto() { ImageCapture imageCapture = new ImageCapture.Builder() //优化捕获速度,可能降低图片质量 .setCaptureMode(ImageCapture.CAPTURE_MODE_MINIMIZE_LATENCY) //设置宽高比 .setTargetResolution(new Size(640, 480)) //设置初始的旋转角度 .build(); String dirPath = getExternalfilesDir("").getabsolutePath() + file.separator + "TestRecode"; file dirfile = new file(dirPath); if (!dirfile.exists()) { boolean mkdir = dirfile.mkdir(); Log.e(TAG, "takePhoto: mkdir:" + mkdir); } file file = new file(dirfile, System.currentTimeMillis() + ".jpg"); if (!file.exists()) { try { boolean newfile = file.createNewfile(); Log.e(TAG, "takePhoto: newfile:" + newfile); } catch (IOException e) { e.printstacktrace(); } } ImageCapture.OutputfileOptions outputfileOptions = new ImageCapture.OutputfileOptions.Builder(file).build(); mProcessCameraProvIDer.bindTolifecycle((lifecycleOwner) mActivity, CameraSelector.DEFAulT_BACK_CAMERA, imageCapture ); imageCapture.takePicture(outputfileOptions, ContextCompat.getMainExecutor(mActivity), new ImageCapture.OnImageSavedCallback() { @OverrIDe public voID onImageSaved(@NonNull ImageCapture.OutputfileResults outputfileResults) { Log.e(TAG, "onImageSaved: " + outputfileResults); Uri savedUri = outputfileResults.getSavedUri(); Log.e(TAG, "onImageSaved: " + savedUri); if (savedUri == null) { savedUri = Uri.fromfile(file); } Toast.makeText(mActivity, "拍摄成功", Toast.LENGTH_SHORT).show(); } @OverrIDe public voID one rror(@NonNull ImageCaptureException exception) { Log.e(TAG, "onError: " + exception); } }); }
录制视频
使用VIDeoCapture相关的API实现视频录制的功能
@Suppresslint("RestrictedAPI") private voID startRecorder() { mVIDeoCapture = new VIDeoCapture.Builder() .build(); String dirPath = getExternalfilesDir("").getabsolutePath() + file.separator + "TestRecode"; file dirfile = new file(dirPath); if (!dirfile.exists()) { boolean mkdir = dirfile.mkdir(); Log.e(TAG, "startRecorder: mkdir:" + mkdir); } file file = new file(dirfile, System.currentTimeMillis() + ".mp4"); if (!file.exists()) { try { boolean newfile = file.createNewfile(); Log.e(TAG, "startRecorder: newfile:" + newfile); } catch (IOException e) { e.printstacktrace(); } } mProcessCameraProvIDer.bindTolifecycle( this, CameraSelector.DEFAulT_BACK_CAMERA, mPrevIEw, mVIDeoCapture); mVIDeoCapture.startRecording(file, ContextCompat.getMainExecutor(mActivity), new VIDeoCapture.OnVIDeoSavedCallback() { @OverrIDe public voID onVIDeoSaved(@NonNull file file) { Log.e(TAG, "onVIDeoSaved: " + file); Toast.makeText(mActivity, "录制结束", Toast.LENGTH_SHORT).show(); } @OverrIDe public voID one rror(int vIDeoCaptureError, @NonNull String message, @Nullable Throwable cause) { Log.e(TAG, "onError: " + vIDeoCaptureError + "," + message); Toast.makeText(mActivity, "录制出错:code:" + vIDeoCaptureError + "," + message, Toast.LENGTH_SHORT).show(); mIsRecording = false; } } ); } @Suppresslint("RestrictedAPI") private voID stopRecorder() { if (mVIDeoCapture != null) { mVIDeoCapture.stopRecording(); } }
一开始的时候回调到onError中,vIDeoCaptureError是2,message是Mediamuxer creation Failed!,百度也没有找到解决方法,后来发现是视频文件file没有创建成功,所以要注意检查视频文件file有没有创建成功;
当然别忘记了在程序中先要动态申请相关权限;
以上就是使用CameraX实现摄像头预览、拍照、视频录制功能;
Demo源码地址:https://github.com/maqing-programmer/CameraXDemo
总结以上是内存溢出为你收集整理的Android CameraX实现摄像头预览、拍照、录制视频全部内容,希望文章能够帮你解决Android CameraX实现摄像头预览、拍照、录制视频所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)