首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >CameraX初探

CameraX初探

作者头像
雪月清
发布2020-06-23 16:15:44
1.3K0
发布2020-06-23 16:15:44
举报
文章被收录于专栏:雪月清的随笔雪月清的随笔

起源

针对相机开发涉及专业知识多,且Camera2使用复杂等痛点,在2019年的Google I/O大会上,Google推出了一个新的Jetpack组件--CameraX,这个支持包的作用为: help you make camera app development easier

优势

  1. 适用大部分android设备,且向后兼容至Android5.0(API level 21)
  2. 基于Use Case设计,api使用简单,且代码量更少
  3. 与Lifecycle组件结合,自动管理相机的生命周期
  4. 与主流手机厂商合作,通过CameraX可以使用手机厂商系统相机app独有的人像,美颜,hdr等效果

基本使用

CameraX基于Use Case进行设计,使调用者专注于需要完成的任务,而无需花时间处理不同设备的细微差别, 目前包括三种基本用例:

  1. Preview
  2. Image Analysis
  3. Capture

不管是预览还是图像分析,图片拍摄,CameraX用例的使用都遵循一个统一的基本流程:

  1. 通过建造者模式构建Config类;
  2. 通过Config类创建Case;
  3. 绑定生命周期

CameraX目前处于alpha版本,在使用时需要先添加依赖:

def camera_x_version = "1.0.0-alpha06"
implementation "androidx.camera:camera-core:${camera_x_version}"
implementation "androidx.camera:camera-camera2:${camera_x_version}"

预览

// 1. create config
val previewConfig = PreviewConfig.Builder()
                    .setLensFacing(CameraX.LensFacing.FRONT)
                    .build()                           
// 2. create case
val preview = Preview(previewConfig)  
// 3. register first frame
preview.setOnPreviewOutputUpdateListener {
    mTextureView.surfaceTexture = it.surfaceTexture
} 
// 4. binding
CameraX.bindToLifecycle(this, preview)

拍照

// 1. create config
val imageCaptureBuildConfig = ImageCaptureConfig.Builder()
         .setLensFacing(CameraX.LensFacing.FRONT)
         .setTargetRotation(windowManager.defaultDisplay.rotation)
         .setCaptureMode(ImageCapture.CaptureMode.MAX_QUALITY)
         .build()    
// 2. create case
val capture = ImageCapture(imageCaptureBuildConfig);       
// 3. binding
CameraX.bindToLifecycle(this, capture)      
// 4. take photo
capture.takePicture(...)

图像分析

通过对图像分析用例注册analyze方法(该方法每帧执行一次),我们可以获取到每一帧的图像数据。拿到图像数据后,就可以根据自己的业务进行相关操作了。 图像分析可以分为两种模式:阻塞模式和非阻塞模式。

阻塞模式通过 ImageAnalysis.ImageReaderMode.ACQUIRE_NEXT_IMAGE 设置,在此模式下, 分析器会按顺序从相机接收帧;

非阻塞模式通过 ImageAnalysis.ImageReaderMode.ACQUIRE_LATEST_IMAGE 设置。在此模式下,分析器会从相机接收调用 analyze 方法时的最后一个可用帧。该模式是可能丢帧的。

// 1. create config
val imageAnalysisConfig = ImageAnalysisConfig.Builder()
    .setLensFacing(CameraX.LensFacing.FRONT)
    .setTargetResolution(Size(1280, 720))
    .setImageReaderMode(ImageAnalysis.ImageReaderMode.ACQUIRE_LATEST_IMAGE)
    .build()   
// 2. create case
val imageAnalysis = ImageAnalysis(imageAnalysisConfig)
// 3. register analyzer
imageAnalysis.setAnalyzer(mExecutor, { image: ImageProxy, rotationDegrees: Int ->
    // image format -> YUV_420_888
})
CameraX.bindToLifecycle(this, imageAnalysis)

供应商扩展

手机厂商的系统相机app有很多优秀的相机效果,比如虚化bokeh,hdr,美颜等,第三方相机app可以通过CameraX Extensions使用到这些效果,如果厂商支持,否则采用CameraX的默认实现

// Create a Builder same as in normal workflow.
val builder = ImageCaptureConfig.Builder()
     
// Create a Extender object which can be used to apply extension
// configurations.
val bokehImageCapture = BokehImageCaptureExtender.create(builder)

// Query if extension is available (optional).
if (bokehImageCapture.isExtensionAvailable()) {
    // Enable the extension if available.
    bokehImageCapture.enableExtension()
}

// Finish constructing configuration with the same flow as when not using
// extensions.
val config = builder.build()
val useCase = ImageCapture(config)
CameraX.bindToLifecycle(this as LifecycleOwner, useCase)

CameraX+OpenGL

在预览用例中,通过注册setOnPreviewOutputUpdateListener,可以拿到一个相机图像流的SurfaceTexture, 通过SurfaceTexture的attachToGLContext方法将一个OES纹理关联到GL环境中:

Attach the SurfaceTexture to the OpenGL ES context that is current on the calling thread. A This new texture is bound to the GL_TEXTURE_EXTERNAL_OES texture target.

然后将OES纹理绘制到OpenGL对应的Surface上

DEMO

https://github.com/sifutang/camerax_demo.git

demo效果:

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-03-01,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 雪月清的随笔 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档