HarmonyOS Next鸿蒙开发:二维码组件

534 阅读2分钟

HarmonyOS的官方API中提供了QRCode组件(QRCode-基础组件-组件参考(基于ArkTS的声明式开发范式)-ArkTS API参考-HarmonyOS应用开发),这个组件有个缺点只能用于显示二维码,无法显示条码与解析码内容,下面给大家介绍一个功能强大的三方库@ohos/zxing

最近看了下官方的api有提供Qrcode组件,使用起来也很简单,之前做安卓的时候用的比较多是zxing的开源框架生成二维码,那么好奇的发现也支持了鸿蒙HarmonyOS的第三方库。 官方的提供了一个组件QRCode,可以直接使用 使用很简单

QRCode(this.message).width(100).height(100)

使用zxing的就稍微麻烦点 需要先引入三方库 安装 ohpm install @ohos/zxing ,默认安装是最新版本 安装完成后可以在oh-package.json5中检查下,

使用官方和zxing的完整代码如下:

QrcodePage是页面,也定义了一个工具类ZXQRCodeUtils 详情的zxing使用方式参考:zxing官方说明



import { BarcodeFormat } from '@ohos/zxing';
import ZXQRCodeUtils from './qrCode/ZXQRCodeUtils'
import image from '@ohos.multimedia.image';

@Entry
@Component
struct QrcodePage {
  @State message: string = 'Hello World';
  @State pixelMap : image.PixelMap | undefined = undefined;

  qrcode = new ZXQRCodeUtils()

  async encode() {
    this.pixelMap = await this.qrcode.encode("ode", {
      width: 260,
      height: 80,
      format: BarcodeFormat.QR_CODE
    })
  }
  async decode() {
    try {
      if(this.pixelMap != undefined){
        console.log('[Demo] decode :' + JSON.stringify(this.pixelMap));
          this.message = await this.qrcode.decode(this.pixelMap, {
            width: 200,
            height: 200,
            format: BarcodeFormat.QR_CODE
          })
        console.log('[Demo] decode :' + JSON.stringify(this.message));

      }

    } catch (err) {

      console.log('[Demo] decode error:' + JSON.stringify(err));
    }
  }

  build() {
    Column() {
      Text('normal').fontSize(9).width('90%').fontColor(0xCccccc).fontSize(30)
      QRCode(this.message).width(100).height(100)
      // 设置二维码颜色
      Text('backgroundColor').fontSize(9).width('90%').fontColor(0xCccccc).fontSize(30)
      //二维码背景色
      QRCode(this.message).width(100).height(100).backgroundColor(Color.Orange)

      Image(this.pixelMap).width(260).height(80).margin(30)
      Button('生成二维码').fontSize(25).width(300).margin(20).onClick(() => {
        this.encode();
      })
      Button('解析二维码').fontSize(25).width(300).margin(20).onClick(() => {
        this.decode();
      })

    }.width('100%').margin({ top: 5 })

  }
}



import {
  BarcodeFormat,
  MultiFormatWriter,
  BitMatrix,
  EncodeHintType,
  MultiFormatReader,
  DecodeHintType,
  RGBLuminanceSource,
  BinaryBitmap,
  HybridBinarizer
} from '@ohos/zxing';
import image from '@ohos.multimedia.image';
//import { image } from '@kit.ImageKit';
import { BusinessError } from '@kit.BasicServicesKit';

export  class QrCodeParams {
  constructor() {
  }
  width: number = 0
  height: number = 0
  format: BarcodeFormat =0
}



export default class ZXQRCodeUtils {

  constructor() {

  }


  async encode(content: string, params:QrCodeParams): Promise<image.PixelMap> {
    const qrParam = params
    const encodeHintTypeMap:Map<number, number> = new Map();
    // 设置二维码空白的宽度
    encodeHintTypeMap.set(EncodeHintType.MARGIN, 0);
    const writer: MultiFormatWriter = new MultiFormatWriter();
    let matrix: BitMatrix = writer.encode(content, qrParam.format, qrParam.width, qrParam.height, encodeHintTypeMap);
    const PixelData = this.getMatrixPixelData(matrix, matrix.getWidth(), matrix.getHeight())

    const opts: image.InitializationOptions = {
      //editable: false,// 是否可编辑。当取值为false时,图片不可二次编辑
      //pixelFormat: image.PixelMapFormat.RGBA_8888,
      size: {
        height: qrParam.height, width: qrParam.width
      }
    }
    return await image.createPixelMap(PixelData.buffer, opts)
  }

  async decode(image: image.PixelMap, params: QrCodeParams): Promise<string> {
    const qrParam = params
    let num=image.getPixelBytesNumber()
    let arrayBuffer:ArrayBuffer=new ArrayBuffer(num);
    await image.readPixelsToBuffer(arrayBuffer)
    const int32Array=new Int32Array(arrayBuffer)
    const luminanceSource=new RGBLuminanceSource(int32Array,qrParam.width, qrParam.height)
    const binaryBitmap=new BinaryBitmap(new HybridBinarizer(luminanceSource))
    const reader=new MultiFormatReader()
    const hints=new Map<number,BarcodeFormat[]>();

    hints.set(DecodeHintType.POSSIBLE_FORMATS,[params.format]);
    reader.setHints(hints);
    let result=reader.decode(binaryBitmap);
    let text=result.getText();
    return text;
  }

  getMatrixPixelData(matrix:BitMatrix, width:number, height:number) {
    const BLACK = 0xFF000000;
    const WHITE = 0xFFFFFFFF;
    const pixels = new Uint32Array(width * height);
    for (let y = 0; y < height; y++) {
      let offset = y * width;
      for (let x = 0; x < width; x++) {
        pixels[offset + x] = matrix.get(x, y) ? BLACK : WHITE;
      }
    }
    return pixels;
  }



}

image.png