基于官网demo,增加了对焦、手势缩放、手电、闪光灯等操作
Camera的预备知识
熟悉的大佬可以跳过
Surface、SurfaceView、SurfaceHolder这三个是啥
Surface是什么?一句话来说Surface 是一块用于填充图像数据的内存空间。
可以再深入一点,了解下它包含的东西:咱后面可以重点关注下Buffer转纹理的细节实际上用openGL修改流我们下一章分析
SurfaceView是什么?一句话来描述的话那就是:它一个可以显示surface的view!在App端它仍在View hierachy中,但在WMS中(可以理解为Server端),它与宿主窗口是分离的。这样的好处是对这个Surface的渲染可以放到单独线程去做,不会影响主线程对事件的响应。缺点也很明显,它的显示也不受View的属性控制,所以不能进行平移,缩放等变换(7.0之前)。
SurfaceHolder是什么?它是一个接口,给持有surface的对象使用,可以控制surface的大小和格式,编辑surface中的像素,以及监听surface的变化,这个接口通过SurfaceView获得。下面这张图可以说明一切
Camera介绍
CameraX是什么,能解决什么问题
- Jetpack的一个支持库,最低版本要求Android5.0
- 默认的相机功能还是Camera2的能力,当然API都变了,同时提供CameraX Extensions拓展库可以添加各种特效,例如人像、HDR、夜间和美颜模式(从上图也可以看出,这是依赖OEM的)
- 绑定生命周期,所以Camera本身无需在生命周期中调用什么onPause onResume之类的样板代码,且忘记后会造成各种问题
- 抹平设备兼容性问题,无需在代码库中添加设备专属代码
CameraX如何使用
第一步
引入依赖
// CameraX core library
def camerax_version = '1.0.0-rc03'
// def camerax_version = '1.1.0-alpha03'目前最新版,但是为了稳定我们还是选择rc版
implementation "androidx.camera:camera-core:$camerax_version"
// CameraX Camera2 extensions[可选]拓展库可实现人像、HDR、夜间和美颜、滤镜但依赖于OEM
implementation "androidx.camera:camera-camera2:$camerax_version"
// CameraX Lifecycle library[可选]避免手动在生命周期释放和销毁数据
implementation "androidx.camera:camera-lifecycle:$camerax_version"
// CameraX View class[可选]最佳实践,最好用里面的PreviewView,它会自行判断用SurfaceView还是TextureView来实现
implementation 'androidx.camera:camera-view:1.0.0-alpha23'
第二步
添加布局控件
<androidx.camera.view.PreviewView
android:id="@+id/view_finder"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
第三步
初始化cameraProviderFuture
并得到cameraProvider
/** Initialize CameraX, and prepare to bind the camera use cases */
//UseCase实际上是一个抽象类,相机中最核心的几个类的父类ImageAnalysis/ImageCapture/Preview/VideoCapture
private fun setUpCamera() {
val cameraProviderFuture = ProcessCameraProvider.getInstance(requireContext())
cameraProviderFuture.addListener(Runnable {
// CameraProvider
cameraProvider = cameraProviderFuture.get()
// 选择默认摄像头给后续使用
lensFacing = when {
hasBackCamera() -> CameraSelector.LENS_FACING_BACK
hasFrontCamera() -> CameraSelector.LENS_FACING_FRONT