Skip to content

Latest commit

 

History

History
133 lines (119 loc) · 9.23 KB

README.md

File metadata and controls

133 lines (119 loc) · 9.23 KB

CameraZ

介绍

CamearZ是自主开发且开源的一个Android相机预览SDK,目前已推广应用在公司内部的一些模块,目的是希望通过最简单的接口帮助开发者完成Android相机的功能调用,不用费心考虑camera和surface的生命周期。支持以下功能:

  1. 快捷预览:只用几行代码就可以实现相机预览,且同时支持camera1和camera2接口,实测全屏下预览效果在OPPO Find N及HUAWEI P10上优于HUAWEI的统一扫码服务
  2. 快捷扫码:对zxing库做了简单修改,配合cameraz可快速实现一个扫码功能;
  3. 变形预览:支持矩形、圆形等不同形状预览,且支持预览窗口拖拽和双指缩放变焦;
  4. 前后摄预览:支持同时打开前后主摄像头进行双窗口预览;
  5. 后置多摄预览:在手机厂商HAL支持camera2的前提下,可打开后置多颗摄像头实现预览拍照。

更多详细介绍:【语雀】【CameraZ】个人开源的安卓相机预览SDK

架构

相机架构 (4).png
相机架构 (3).png

  1. APP层提供少量且简单的入口:打开相机,设置参数,预览/拍照/录制,暂停,关闭等;
  2. Manager负责生成(Producer)、监听(Listener)和管理Client;
  3. Client是给业务端使用的相机客户端,业务方不仅可以使用自己定义的预览surface,还可以一键使用CameraZ已经封装好的预览实现,真正做到零代码接入;
  4. Client为内部实现的预览提供了自定义的装饰器或者叫滤镜,通过proxy1或者proxy2(分别对应camera1和camera2的代理实现),调用原生API。

接入

引入依赖

//需要在根build.gradle引入仓库:mavenCentral
repositories {
    mavenCentral()
}
...
//引入预览库
implementation "io.github.hello-cqq:cameraz:1.0.0"
//引入条码库
implementation "io.github.hello-cqq:barcode:1.0.0"

扫码使用举例

private lateinit var cameraZ: CameraZ
private lateinit var decoder: Decoder
private var backCameraId = "0"

private val previewCallback: PreviewCallback = object : PreviewCallback {
    override fun onPreviewFrame(data: ByteArray?, size: Size, format: Int) {
        decodeCode(data, size, format)
    }
}

override fun onCreate() {
    super.onCreate()
    //获取相机管理实例
    cameraZ = CameraZ.getInstance(this.applicationContext)
    decoder = Decoder()
    //获取后置主摄id,通常为0
    backCameraId = CameraConfigUtil.getBackCameraList()[0].toString()
}

override fun onResume() {
    super.onResume()
    //使用camera1接口启动相机,建议在onResume执行,因为通常我们还需要申请相机等权限
    cameraZ.open(
        backCameraId,
        object : CameraStateCallback {
            override fun onOpened(client: CameraClient) {
                Log.d(TAG, "onOpened")
                cameraView = findViewById(R.id.camera_view)
                //可选,绑定相机生命周期到Activity
                client.bind(this@SuperScanActivity)
                //打开预览
                client.startPreview(cameraView!!, TAG, previewCallback)
            }
        },
        1
    )
}

//解码
private fun decodeCode(data: ByteArray?, size: Size, format: Int) {
    val results = data?.let {
        if (format == ImageFormat.NV21) {
            decoder.decode(it, format, size, null, null)
        } else {
            val bitmap = BitmapFactory.decodeByteArray(it, 0, it.size)
            decoder.decode(bitmap)
        }
    }
}

//拍照
private fun clickShotBtn() {
    cameraClient?.let {
        it.takePicture(TAG, pictureCallback)
    }
}

//关闭
override fun onDestroy() {
    super.onDestroy()
    //关闭相机
    cameraZ.closeAll()
    //注意,仅在彻底不使用时再释放(线程)
    cameraZ.release()
}

预览

常见的预览问题

1. 预览拉伸?

相机分辨率与Surface比例不一致导致

2. 预览卡顿?

相机分辨率太大或UI线程操作相机

CameraZ 预览算法

  1. 任意期望的预览分辨率为,相机所支持的分辨率数组为;
  2. 按分辨率尺寸从大到小排序,得到
  3. 遍历,并取出所有同时满足以下两个条件的项:

得到新的相机支持的分辨率数组

  1. 按相机分辨率比例与期望分辨率比例插值从小到大排序,得到
  2. 的第一项,得到最佳的相机预览分辨率,即,如下图形表示:

CameraS预览算法.png

  1. 通常的值与屏幕大小一致,需要将b按照的比例进行向上调整surface的宽高,最终预览正常。

方案对比

这里用华为开发者平台的开放能力——统一扫码服务做对比,从官网下载的demo,设备使用了OPPO FindN和HUAWEI P10。在折叠屏Find N和华为p10机器上,CameraZ的预览是正常的,而HUAWEI的demo都存在不同程度的拉伸问题,这是因为我们快捷扫码自定义了一套可以适配所有预览窗口大小的预览算法。
下图左边是CameraZ,右边是HUAWEI统一扫码服务。
image.png