积分143 / 贡献0

提问0答案被采纳0文章10

[经验分享] OpenHarmony Flutter扫码功能插件开发 原创

深开鸿_石悌君 显示全部楼层 发表于 7 天前

扫码是手机常用功能,适配fluttertpc_mobile_scanner时发现安卓和OpenHarmony略有差异;解析如下

安卓实现方案

安卓插件的扫码基于com.google.mlkit.vision.barcode.BarcodeScanning库实现;

对本地图片进行扫码的核心流程如下

var scanner = BarcodeScanning.getClient() //定义scanner
    fun analyzeImage(image: Uri, analyzerCallback: AnalyzerCallback) {
        val inputImage = InputImage.fromFilePath(activity, image)

        scanner.process(inputImage) //调用scanner.process得到扫码结果
            .addOnSuccessListener { barcodes ->
                val barcodeMap = barcodes.map { barcode -> barcode.data }

                if (barcodeMap.isNotEmpty()) {
                    analyzerCallback(barcodeMap)
                } else {
                    analyzerCallback(null)
                }
            }
    }

通过相机扫码仍然借用图片扫码流程:先调用相机拍照接口得到照片,再调用scanner.process得到扫码结果

OpenHarmony实现方案

OpenHarmony自带ScanKit,可以方便实现扫码功能

图片扫码

图片扫码很简单,使用即可获得扫码结果

import { scanCore, scanBarcode, detectBarcode } from '@kit.ScanKit';
analyzeImage(call: MethodCall, result: MethodResult) {
    const options: scanBarcode.ScanOptions = {
        scanTypes: [scanCore.ScanType.ALL],
        enableMultiMode: true,
        enableAlbum: true
    }

    let inputImage: detectBarcode.InputImage = { uri: call.args }
    detectBarcode.decode(inputImage, options, (error: BusinessError, scanResult: Array<scanBarcode.ScanResult>) => {
    })
}

相机扫码

相机扫码如果借鉴安卓流程也不是不行,但OpenHarmony提供了customeScan模块,实现更加简单

重点流程如下

import { customScan, scanBarcode, scanCore, detectBarcode } from '@kit.ScanKit';
async start(call: MethodCall, result: MethodResult) {
    const options: scanBarcode.ScanOptions = {
        scanTypes: scanTypes,
        enableMultiMode: true,
        enableAlbum: true
    }
    customScan.init(options); //必须先调用

    const viewControl: customScan.ViewControl = {
      width: cameraWidth,
      height: cameraHeight,
      surfaceId: this.surfaceId!,
    };

    customScan.start(viewControl, this.scanCallback, this.frameCallback)
}

//扫码结果的回调
private scanCallback: AsyncCallback<scanBarcode.ScanResult[]> =
    async (error: BusinessError, result: scanBarcode.ScanResult[]) => {
    //处理扫码结果
}

//扫码时图像的回调
private frameCallback: AsyncCallback<customScan.ScanFrame> =
    async (error: BusinessError, frameResult: customScan.ScanFrame) => {

}

frameCallback这个回调就比安卓方便多了,不需要调用一堆相机接口得到图像

相机图像的转码

frameCallback中返回的图像数据是YUV格式,需要转码成jpg等格式才能正确显示;这里需要用到imageKit系列函数,代码如下

private frameCallback: AsyncCallback<customScan.ScanFrame> =
    async (error: BusinessError, frameResult: customScan.ScanFrame) => {
    let sourcePotions: image.SourceOptions = {
        sourceDensity: 120,
        sourcePixelFormat: image.PixelMapFormat.NV21,
        sourceSize: { height: this.scanHeight, width: this.scanWidth }
    }
    let imageResource = image.createImageSource(frameResult.byteBuffer, sourcePotions)
    let opts: image.InitializationOptions = {
        editable: true,
        pixelFormat: 3,
        size: { height: this.scanHeight, width: this.scanHeight }
    }
    let pixelMap: image.PixelMap = await imageResource.createPixelMap(opts)
    let packer: image.ImagePacker = image.createImagePacker()
    let packingOpt: image.PackingOption = { format: "image/jpeg", quality: 100 }
    let imgBuffer = await packer.packing(pixelMap, packingOpt);

}

参考资料

fluttertpc_mobile_scanner鸿蒙化代码

©著作权归作者所有,转载或内容合作请联系作者

您尚未登录,无法参与评论,登录后可以:
参与开源共建问题交流
认同或收藏高质量问答
获取积分成为开源共建先驱

Copyright   ©2023  OpenHarmony开发者论坛  京ICP备2020036654号-3 |技术支持 Discuz!

返回顶部