DUICUO

HarmonyOS オープンソースサードパーティコンポーネント - Zbar_ohos バーコードリーダー

[[389913]]

詳細については、以下をご覧ください。

51CTOとHuaweiが共同で構築したHarmonyOSテクノロジーコミュニティ。

https://harmonyos..com

序文

AndroidプラットフォームベースのバーコードリーダーコントロールであるZBar(https://github.com/ZBar/ZBar)がHarmonyOSに移行およびリファクタリングされました。コードはオープンソース化されています(https://gitee.com/isrc_ohos/ZBar)。ぜひダウンロードしてご利用いただき、貴重なフィードバックをお寄せください。

背景

Zbar-ohosは、HarmonyOSシステムをベースとしたバーコードリーダーです。EAN-13/UPC-A、UPC-E、EAN-8、Code 128、CODE39、Codabar、QRコードの認識をサポートし、バーコード登録、バーコードムービーの閲覧、バーコードログインなど、様々な分野で広く利用されています。

コンポーネント効果表示

1. 権限を追加する

ソフトウェアを開くと、図 1 に示すように、カメラの権限を追加するプロンプトが表示されます。「常に許可」ボタンをクリックし、ソフトウェアを再起動して (UI を更新して) バーコードをスキャンします。

図1 QRコードスキャンインターフェース

2. スキャン結果

スキャンインターフェースは、位置合わせツールとステータスバーの2つの部分で構成されています。位置合わせツールにはカメラで撮影した画像が表示され、スキャンするにはバーコードをこの領域内に配置する必要があります。ステータスバーには、現在のスキャンステータスまたはスキャン結果が表示されます。

(1)一次元バーコードスキャン

一次元バーコードは通常、情報を水平方向に伝達しますが、垂直方向には伝達しません。アライナーによる読み取りを容易にするため、バーコードの高さは通常固定されています。

図2は、ZBarコンポーネントが1Dバーコードをスキャンした様子を示しています。カメラがバーコードをスキャンすると、画面下部のステータスバーが「スキャン中」からバーコードのスキャン結果に更新されます。次のバーコードがスキャンされると、ステータスバーのスキャン結果もリアルタイムで更新されます。

図2 バーコードスキャン結果

(2)二次元バーコードスキャン

2次元バーコードは、水平方向と垂直方向の両方の情報を表し、情報容量が大きく、通常は正方形の構造で、セキュリティレベルが高く、英語、中国語、数字、記号、グラフィックなどを直接表示できます。

図3は、ZBarコンポーネントで2Dバーコードをスキャンした様子を示しています。スキャンプロセスは1Dバーコードの場合と同じで、ステータスバーに2Dバーコードのスキャン結果が表示されます。

図3. QRコードスキャン結果

サンプル分析

サンプルセクションでは、まずカメラデバイスを作成・設定し、カメラで取得した生データをライブラリに渡してスキャン処理を行い、最後にスキャン結果を取得して画面に表示します。サンプルセクションのコードの詳細は以下をご覧ください。

1. カメラクラスのオブジェクトを生成する

CameraKitクラスはカメラ機能を使用するためのエントリを提供し、CameraStateCallbackImplクラスはカメラの作成と実行のためのコールバックです。ここでは、CameraKitクラスを使用してCameraオブジェクトが生成されます。通常とは異なり、CameraKitクラスはCameraオブジェクトを直接返すのではなく、CameraStateCallbackImplコールバックから取得します。

  1. プライベートvoid openCamera(){
  2. // CameraKitオブジェクトを取得する
  3. カメラキット = CameraKit.getInstance(これ);
  4. カメラキットがnull場合
  5. 戻る;
  6. }
  7. 試す {
  8. // 現在のデバイスの論理カメラのリストを取得します (cameraIds)
  9. 文字列[] cameraIds = cameraKit.getCameraIds();
  10. カメラIDの長さが0以下の場合
  11. System.out.println ( "cameraIdsのサイズは0です" );
  12. }
  13. // カメラの作成と操作に使用されるコールバック
  14. カメラ状態コールバック実装 cameraStateCallback = 新しいカメラ状態コールバック実装();
  15. カメラ状態コールバックnullの場合
  16. System.out.println ( "cameraStateCallback は null です" );
  17. }
  18. // カメラを実行するスレッドを作成する
  19. イベント ハンドラー eventHandler = 新しいイベント ハンドラー ( EventRunner.create ( "CameraCb" ));
  20. イベントハンドラがnull場合
  21. System.out.println ( "eventHandlerはnullです" );
  22. }
  23. // カメラを作成する
  24. cameraKit.createCamera(cameraIds[0], cameraStateCallback, eventHandler);
  25. } キャッチ (IllegalStateException e) {
  26. System.out.println ( "getCameraIds 失敗" );
  27. }
  28. }

2. カメラを取り付けたSurface

サーフェスは、プレビュー、写真の撮影、ビデオの録画といったカメラ機能を実装するために使用されます。ここでは、カメラ用にpreviewSurfaceとdataSurfaceという2つのサーフェスを追加します。前者はカメラでキャプチャしたインターフェースを表示し、後者はカメラでキャプチャしたデータを読み取って処理します。

  1. プライベート最終クラスCameraStateCallbackImplはCameraStateCallbackを拡張します{
  2. // カメラ作成とカメラ実行時のコールバック
  3. @オーバーライド
  4. パブリックvoid onCreated(カメラカメラ) {
  5. mcamera = camera; // カメラオブジェクトを取得する
  6. カメラ設定ビルダー cameraConfigBuilder = camera.getCameraConfigBuilder();
  7. カメラ設定ビルダーnullの場合
  8. System.out.println ( "onCreated cameraConfigBuilder は null です" );
  9. 戻る;
  10. }
  11. // サーフェス構成のプレビュー
  12. cameraConfigBuilder.addSurface(プレビューサーフェス)。
  13. // データ処理用にサーフェスを構成する
  14. dataSurface = imageReceiver.getRecevingSurface();
  15. cameraConfigBuilder.addSurface(データサーフェス);
  16. 試す {
  17. // カメラ機器の構成
  18. カメラを設定します(cameraConfigBuilder.build());
  19. } キャッチ (IllegalArgumentException e) {
  20. System.out.println ( "引数例外" );
  21. } キャッチ (IllegalStateException e) {
  22. System.out.println ( "状態例外" );
  23. }
  24. }
  25. }

3. ループフレームキャプチャを有効にする

ユーザーは通常、画像をキャプチャした後に写真を撮ったり、その他の操作を行ったりします。ループフレームキャプチャを有効にすると、dataSurfaceはカメラからデータを取得できます。

  1. @オーバーライド
  2. パブリックvoid onConfigured(カメラカメラ) {
  3. // プレビュー構成テンプレートを取得する
  4. FrameConfig.Builder frameConfigBuilder = mcamera.getFrameConfigBuilder(FRAME_CONFIG_PREVIEW);
  5. // サーフェス構成のプレビュー
  6. frameConfigBuilder.addSurface(プレビューサーフェス)。
  7. // カメラが設定されたサーフェス
  8. frameConfigBuilder.addSurface(データサーフェス);
  9. 試す {
  10. // ループフレームキャプチャを開始する
  11. intトリガー ID = mcamera.triggerLoopingCapture(frameConfigBuilder.build());
  12. } キャッチ (IllegalArgumentException e) {
  13. System.out.println ( "引数例外" );
  14. } キャッチ (IllegalStateException e) {
  15. System.out.println ( "状態例外" );
  16. }
  17. }

4. カメラデータをスキャンする

dataSurface のデータはカメラの生データであり、YUV420 形式です。これを Image クラスのデータとしてカプセル化してから、ImageScanner クラスに渡して実際にスキャンする必要があります。

  1. // カメラの生のデータが画像データにカプセル化される
  2. 画像バーコード = new Image(mImage.getImageSize().width,mImage.getImageSize().height, "Y800" );
  3. バーコード.setData(YUV_DATA);
  4. //画像データのスキャン
  5. int結果 = scanner.scanImage(バーコード);

5. プレビューデータのスキャン結果を表示します。

アライナーには複数のバーコードが含まれる可能性があり、ImageScannerクラスにも複数のスキャン結果が含まれる可能性があるため、最終的に返されるスキャン結果はSymbolSet型になります。このデータ型は複数のSymbolデータを保持できるコンテナであり、各Symbolデータはバーコードのスキャン結果を表します。

  1. // 複数の Symbol データを保持できる SymbolSet という名前のコンテナーを作成します。
  2. シンボルセット syms = scanner.getResults();
  3. // SymbolSet 内の各要素を反復処理します
  4. (シンボル sym: syms)の場合{
  5. ハンドラー.postTask(新しい実行可能() {
  6. @オーバーライド
  7. パブリックvoid run() {
  8. scanText.setText( "スキャン結果:" + sym.getData()); // シンボルから情報を取得します
  9. scanText.invalidate();
  10. }
  11. });

ライブラリ分析

ライブラリセクションは主にdataSurfaceをスキャンします。dataSurfaceには、(1) カメラの生データを画像データにカプセル化する機能と、(2) 画像データをスキャンする機能という2つの主要な機能があります。この部分は主にC言語で実装されているため、ここでは基本的な原則と主要なインターフェースのみを説明し、基盤となるコードは示しません。

(1)カメラの生のデータは画像データにカプセル化される

画像は、一般的なYUVおよびRGBデータを含む複数のデータ形式をサポートしています。ここで必要な画像データは「Y800」または「GRAY」型であり、バーコードスキャンデータには画像のグレースケールデータのみが必要であることを意味します。

  1. パブリックネイティブvoid setData(byte[] data);

(2)画像データをスキャンする

`scanImage()` メソッドは、入力画像データをスキャンするために使用されます。このプロセスでは、まず入力画像の構成を検証し、次にジグザグパターンに沿って1ピクセルずつラインごとにスキャンします。また、スキャンされたデータのフィルタリング、エッジ勾配の計算、勾配の適応的な閾値設定、エッジの判定を行います。最後に、スキャンされたデータは輝度と幅のストリームに変換されます。輝度と幅のストリームの変化パターンは、スキャンされているバーコードの種類を示し、その後、固定のデコード方法を使用してデコードされ、バーコード情報が得られます。

  1. public native int scanImage(イメージ image);

プロジェクト貢献者

チェン・コンシャオ、ジェン・センウェン、ジュー・ウェイ、チェン・メイルー、チャン・シンシン

詳細については、以下をご覧ください。

51CTOとHuaweiが共同で構築したHarmonyOSテクノロジーコミュニティ。

https://harmonyos..com