如果您更喜欢通过视频了解此内容,请在此处查看:
CameraX是一个为了简化编写相机应用而设计的支持库,它所提供的高级API可以让开发者专注于和用户交互而非相机的内部实现。我们一直在探索并修复其背后复杂的兼容性问题,让每个新版本都得以在更多的设备上稳定运行。
何时使用CameraX或Camera2,这取决于您期望更快的开发速度或是想要更高的自定义程度。
CameraX基于主要的使用场景来构建,比如实时预览相机、检索缓冲区以进行分析和拍摄照片,在CameraX1.1版本中还加入了视频拍摄功能。我们来看一个简单的CameraX示例:
funbindPreview(cameraProvider:ProcessCameraProvider){//使用CameraX创建Preview用例varpreview:Preview=Preview.Builder().build()//创建cameraSelector,它会在设备上搜索所需的相机varcameraSelector:CameraSelector=CameraSelector.Builder()//在本例中,我们选择搜索后置相机.requireLensFacing(CameraSelector.LENS_FACING_BACK).build()//从CameraX的CameraView包中获取previewView的句柄//利用此方法可以轻松的将相机内容添加到视图上preview.setSurfaceProvider(previewView.getSurfaceProvider())//将preview与其生命周期绑定varcamera=cameraProvider.bindToLifecycle(thisasLifecycleOwner,cameraSelector,preview)}△CameraX代码示例
CameraX是生命周期感知型组件,这意味着它将自动处理应用的生命周期事件来实现开始、停止、暂停和恢复。现在,应用启动时屏幕上便会显示实时预览。
我们已于2021年5月发布了1.0稳定版本,目前正在开发1.1Alpha版本并且很快将会进入Beta阶段。并且我们一如既往地不断为新增设备推出兼容性修复程序,例如1.0.1和1.0.2。
在CameraX1.1版本中我们新增了开发者呼声很高的功能,具体而言,在本文中我们将重点介绍:
在CameraX1.1版本中我们加入了视频拍摄功能,视频拍摄API(尚处于Alpha阶段,细节可能会发生变化,但整体结构基本会保持不变)提供了录制到文件等基本功能、可自动适配每台设备的QualitySettingAPI,以及LifecycleManagementAPI。接下来我们先来了解如何设定视频拍摄功能,代码示例如下:
另一个呼声很高的功能是YUV到RGB的转换,我们来了解一下此功能。
△YUV格式(图左)转换至RGB格式(图右)
相机通常以YUV420格式生成数据,其中包括明亮度(Luminance,Y)、色度(Chroma,U,V)和一些填充字节以将各行与有效的内存步幅对齐。但是这种格式的图像处理起来可能很麻烦,而现在CameraX可以将ImageAnalysis的输出转换为大家更熟悉的RGBA以方便处理。接下来我们看一个示例:
valimageAnalysis=ImageAnalysis.Builder().setTargetResolution(Size(1280,720)).setOutputImageFormat(ImageAnalysis.OUTPUT_IMAGE_FORMAT_RGBA_8888).setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST).build()△从ImageAnalysis获取RGB输出
在示例代码中,我们创建了ImageAnalysis实例,为图像缓冲区指定了所需的分辨率和背压策略,并调用新的setOutputImageFormat方法以请求RGBA8888格式的输出。现在,ImageAnalysis输出的帧为RGBA8888数据而不再是YUV格式。
CameraX中YUV到RGB的转换基于libyuv。此外,在CameraX1.1版本中数据本身可以转换到目标分辨率。在中端设备上对图像大小为640x480至1080p的数据进行转换大约需要5~10毫秒,具体性能因设备而异。此外APK会略微增加50KB左右。
修复单像素漂移
YUV转换还修复了部分设备上存在的单像素漂移问题。在这些设备上,YUV输出经过桶形移位一个像素,导致最右边的一列数据出现在图像的左边缘。在已知会发生这种情况的设备上,进行YUV到RGB的转换及输出YUV或RGB都会被修复,并且CameraX将会持续对更多有需要的设备进行修复。
△修复单像素漂移
相机特效
在CameraX1.1中的CameraXExtensionsAPI可以更为充分地发挥设备强大的功能。
CameraXExtensions包括一些最常见的内置相机特效:
我们来看看如何使用CameraXExtensionsAPI:
//获取后置相机列表valcameraSelector=CameraSelector.DEFAULT_BACK_CAMERA//检查所有的后置相机中是否有支持焦外虚化if(extensionsManager.isExtensionAvailable(cameraProvider,cameraSelector,ExtensionMode.BOKEH)){//创建扩展cameraSelector,我们提供了相机并指定焦外虚化模式//它将开始在后台搜索支持焦外虚化的后置相机valbokehCameraSelector=extensionsManager.getExtensionCameraSelector(cameraProvider,cameraSelector,ExtensionMode.BOKEH)//创建imageCapture和previewvalimageCapture=ImageCapture.Builder().builder()valpreview=Preview.Builder().build()//使用bokehCameraSelector将它们绑定到生命周期cameraProvider.bindToLifecycle(lifecycleOwner,bokehCameraSelector,imageCapture,preview)}△以BOKEH效果捕捉并预览图像
在上面的例子中,imageCapture输出的图像将会具有焦外虚化效果,如果设备支持的话,preview也将预览焦外虚化效果。
曝光补偿
CarmeraX1.1中还添加了曝光补偿API,此功能可以帮助用户更好地捕捉过度曝光或者曝光不足的区域。
如图所示我们所处的场景窗外很明亮而室内很昏暗,此时则可以调整曝光补偿来更好地捕捉明亮的室外或昏暗的室内场景。我们来看一个例子:
//创建变量来跟踪exposureIndex值varexposureIndex=0//使用cameraSelector将imageCapture和preview绑定到生命周期valcamera=cameraProvider.bindToLifecycle(lifecycleOwner,getCameraSelector(),preview,imageCapture)//为视图中的按钮添加点击事件evButton.setOnclickListener{//检查有效的范围以防止可能的异常valrange=camera.cameraInfo.exposureState.exposureCompensationRangeif(range.contains(exposureIndex+1)){//调用camera.cameraControl的setExposureCompenstation()方法来设置曝光补偿camera.cameraControl.setExposureCompenstation(++exposureIndex)//使用exposureCompensationStep来实现从index到EV到转换valev=camera.cameraInfo.exposureState.exposureCompensationStep.toFloat()*exposureIndexLog.i("CameraXLog","EV:$ev")}}△通过按钮调整曝光
其中exposureIndex是一个与设备无关的数字,它将以硬件允许的最小步长递增或递减曝光值,因此可以在不同的设备上以类似的方式运作。如果您想向用户展示EV值,可以获取exposureCompensationStep来实现转换。
平滑缩放
在CameraX1.1中,我们还增加了平滑缩放功能。有一些设备有包括广角和长焦在内的多个镜头,CameraX可以检测这些设备是否支持SMOOTH_ZOOM框架,在受支持的设备上使用CameraX的缩放控件时,会自动使用所有的相机来实现更大的缩放范围。如果您已经在使用这个缩放控件,那当您使用1.1版本进行编译时,您的应用应该就可以访问这些设备上的所有相机。
接下来介绍我们在1.1中添加的更多功能。
希望对CameraX1.1版本的简要介绍对大家有所帮助,非常期待看到大家使用CameraX构建的功能!