OpenHarmony开发者论坛

标题: OpenHarmony Flutter扫码功能插件开发 [打印本页]

作者: 深开鸿_石悌君    时间: 7 天前
标题: OpenHarmony Flutter扫码功能插件开发
[md]扫码是手机常用功能,适配fluttertpc_mobile_scanner时发现安卓和OpenHarmony略有差异;解析如下

## 安卓实现方案

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

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

```kotlin
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,可以方便实现扫码功能

### 图片扫码

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

```typescript
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模块,实现更加简单

重点流程如下

```typescript
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系列函数,代码如下

```typescript
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鸿蒙化代码](https://gitee.com/openharmony-sig/fluttertpc_mobile_scanner)

[/md]




欢迎光临 OpenHarmony开发者论坛 (https://forums.openharmony.cn/) Powered by Discuz! X3.5