CameraX小试牛刀,实现二维码扫描

栏目: Android · 发布时间: 5年前

内容简介:在今年的Google I/O大会上,Google新推出了CameraX支持包,按照官方的说法, 这个包的作用是google在几年前推出了Camera2 API用于取代Camera1, 大部分开发者还是喜欢使用Camera1的api,一是因为api太难用,二是要兼容5.0之前的s设备,这次推出的CameraX支持包不仅消除各种使用上的障碍,还与大受好评的archecture component 包的Lifecycle结合,自动管理相机的生命周期,开发者不在需要去关心什么时候打开相机,什么时候释放相机。甚至联系

在今年的Google I/O大会上,Google新推出了CameraX支持包,按照官方的说法, 这个包的作用是

help you make camera app development easier

google在几年前推出了Camera2 API用于取代Camera1, 大部分开发者还是喜欢使用Camera1的api,一是因为api太难用,二是要兼容5.0之前的s设备,这次推出的CameraX支持包不仅消除各种使用上的障碍,还与大受好评的archecture component 包的Lifecycle结合,自动管理相机的生命周期,开发者不在需要去关心什么时候打开相机,什么时候释放相机。甚至联系各个手机厂商提供统一的api调用使用美颜等接口。

关于cameraX的介绍本文不在赘述,将使用cameraX实现一个小功能:使用最少的代码实现二维码解码,在这个demo中将会使用到CameraX中三大功能中的两个:

  • preview
  • analysis

创建app

创建app,声明相机权限

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          xmlns:tools="http://schemas.android.com/tools" package="github.hotstu.camerax.qrcodec">

    <uses-permission android:name="android.permission.CAMERA"/>

    <application
            android:allowBackup="true"
            android:icon="@mipmap/ic_launcher"
            android:label="@string/app_name"
            android:roundIcon="@mipmap/ic_launcher_round"
            android:supportsRtl="true"
            android:theme="@style/AppTheme" tools:ignore="GoogleAppIndexingWarning">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>

                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>
    </application>

</manifest>
复制代码

添加相关依赖

implementation 'com.tbruyelle.rxpermissions2:rxpermissions:0.9.5'
    def camerax_version = "1.0.0-alpha02"
    implementation "androidx.camera:camera-core:${camerax_version}"
    // If you want to use Camera2 extensions.
    implementation "androidx.camera:camera-camera2:${camerax_version}"
    implementation 'com.google.zxing:core:3.3.2'
复制代码

注意,这里有个坑, 因为camerax还没有发布正式版,而它依赖的 androidx.core:core:1.1.0-rc1AppcompatActivity 居然不是 LifeCycleOwner ,,然而camerax依赖 LifeCycleOwner 才能管理生命周期,所以要祭出在support liabary时代解决依赖冲突的黄金代码:

subprojects {
    configurations.all {
        resolutionStrategy {
            force "androidx.core:core:1.0.2"
        }
    }
}
复制代码

编写代码实现摄像头预览

val previewConfig = PreviewConfig.Builder().apply {
            setTargetAspectRatio(Rational(1, 1))
            setTargetResolution(Size(640, 640))
        }.build()
        val preview = Preview(previewConfig)
       preview.setOnPreviewOutputUpdateListener {
            textureView.surfaceTexture = it.surfaceTexture
        }
        CameraX.bindToLifecycle(this@MainActivity, preview)
复制代码

编写代码实现数据分析回调

数据分析可以指定回调的线程

val analysisConfig = ImageAnalysisConfig.Builder().apply {
            setImageReaderMode(ImageAnalysis.ImageReaderMode.ACQUIRE_LATEST_IMAGE)
            val analyzerThread = HandlerThread("BarcodeAnalyzer").apply { start() }
            setCallbackHandler(Handler(analyzerThread.looper))
        }.build()

        val analysis = ImageAnalysis(analysisConfig)
        analysis.analyzer = QRcodeAnalyzer()

        CameraX.bindToLifecycle(this@MainActivity, analysis)
复制代码

同时绑定预览和分析,并且搞定权限申请

class MainActivity : AppCompatActivity() {

    @SuppressLint("CheckResult")
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val previewConfig = PreviewConfig.Builder().apply {
            setTargetAspectRatio(Rational(1, 1))
            setTargetResolution(Size(640, 640))
        }.build()

        val analysisConfig = ImageAnalysisConfig.Builder().apply {
            setImageReaderMode(ImageAnalysis.ImageReaderMode.ACQUIRE_LATEST_IMAGE)
            val analyzerThread = HandlerThread("BarcodeAnalyzer").apply { start() }
            setCallbackHandler(Handler(analyzerThread.looper))
        }.build()

        val rxPermissions = RxPermissions(this)
        val preview = Preview(previewConfig)
        val analysis = ImageAnalysis(analysisConfig)

        preview.setOnPreviewOutputUpdateListener {
            textureView.surfaceTexture = it.surfaceTexture
        }

        analysis.analyzer = QRcodeAnalyzer()
        rxPermissions.request(android.Manifest.permission.CAMERA)
                .subscribe {
                    CameraX.bindToLifecycle(this@MainActivity,
                            preview,
                            analysis)
                }
    }
}
复制代码

实现QRcodeAnalyzer

做二维码解码,很多开发者是直接在zxing-Android 项目基础上删删改改,其实不建议这样做,应为那个项目是从Android早期版本开始的,一些东西都为了支持老版本系统而做出了妥协,很多代码都显得老旧而且不优雅,查看源码你会发现它调用摄像头的方法是非常复杂的。这里我们只是用xzing核心库 com.google.zxing:core

class QRcodeAnalyzer : ImageAnalysis.Analyzer {
    private val reader: MultiFormatReader = MultiFormatReader()

    init {
        val map = mapOf<DecodeHintType, Collection<BarcodeFormat>>(
            Pair(DecodeHintType.POSSIBLE_FORMATS, arrayListOf(BarcodeFormat.QR_CODE))
        )
        reader.setHints(map)
    }

    override fun analyze(image: ImageProxy, rotationDegrees: Int) {
        if (ImageFormat.YUV_420_888 != image.format) {
            Log.e("BarcodeAnalyzer", "expect YUV_420_888, now = ${image.format}")
            return
        }
        val buffer = image.planes[0].buffer
        val data = ByteArray(buffer.remaining())
        val height = image.height
        val width = image.width
        buffer.get(data)
        //TODO 调整crop的矩形区域,目前是全屏(全屏有更好的识别体验,但是在部分手机上可能OOM)
        val source = PlanarYUVLuminanceSource(data, width, height, 0, 0, width, height, false)

        val bitmap = BinaryBitmap(HybridBinarizer(source))

        try {
            val result = reader.decode(bitmap)
            Log.e("BarcodeAnalyzer", "resolved!!! = $result")
        } catch (e: Exception) {
            Log.d("BarcodeAnalyzer", "Error decoding barcode")
        }

    }
}
复制代码

大功告成, 核心代码不超过100行。

总结

总结一下,目前cameraX还在有待完善,例如处理摄像头的rotation的时候还是非常迷。

项目地址: github.com/hotstu/QRCo…

本人在掘金上写的内容除特别注明以外均为本人原创,转载需经本人同意,欢迎转载分享,请注明出处。


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Beginning Google Maps API 3

Beginning Google Maps API 3

Gabriel Svennerberg / Apress / 2010-07-27 / $39.99

This book is about the next generation of the Google Maps API. It will provide the reader with the skills and knowledge necessary to incorporate Google Maps v3 on web pages in both desktop and mobile ......一起来看看 《Beginning Google Maps API 3》 这本书的介绍吧!

HTML 编码/解码
HTML 编码/解码

HTML 编码/解码

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具