ワークフロー入力プログラマ ガイド

DataWedge 11.3

概要

このガイドでは、ワークフロー入力を使用してデータを取得するアプリを開発する方法を説明します。この例では、身分証明書のスキャンに焦点を当てています。同様の手順は、他の OCR 機能 (ナンバー プレート、車両識別番号 (VIN)、タイヤ識別番号 (TIN)、メーター読み取り)、およびフリーフォーム イメージ キャプチャドキュメント キャプチャに適用されます。

使用されたサンプルの身分証明書

  
米国 (ペンシルバニア州) およびノルウェーの運転免許証の例


身分証明書からデータを取得するアプリの開発方法について、詳細な手順を示すビデオ

ソース コードのファイルをダウンロードします。


要件

  • DataWedge バージョン 11.2 以降 (バージョンを検索)
  • スキャン フレームワーク 32.0.3.6 以降 (バージョンを検索)
  • SD660 プラットフォーム上の Zebra モバイル コンピュータ
  • Android 11 以降
  • モバイル コンピュータの内蔵カメラ
  • Mobility DNA OCR Wedge ライセンス - 次の各 OCR 機能に必要です
    • Mobility DNA ナンバープレート OCR Wedge ライセンス
    • Mobility DNA 身分証明書 OCR Wedge ライセンス
    • Mobility DNA 車両識別番号 OCR Wedge ライセンス
    • Mobility DNA タイヤ識別番号 OCR Wedge ライセンス
    • Mobility DNA 検針 OCR Wedge ライセンス

パッケージの表示

重要: Android 11 (API 30) によろパッケージの表示が制限されているため、Android 11 以降を対象とする DataWedge アプリは、AndroidManifest.xml ファイルに次の <queries> 要素を含める必要があります。

    <queries>
        <package android:name="com.symbol.datawedge" />
    </queries>

データを取得する手順

要約すると、ワークフロー入力を使用してデータを取得する手順は次のとおりです。

  1. DataWedge プロファイルを作成し、アプリケーションに関連付けます。
  2. スキャン結果を受信するようにアプリケーションを構成します。
  3. インテントから文字列データを抽出します。
  4. インテントから画像データを抽出します。

これらの手順の詳細について、次のサブセクションで説明します。

1.DataWedge プロファイルを作成し、アプリケーションに関連付けます

DataWedge でプロファイルを作成し、そのプロファイルをアプリに関連付けて、次のように設定します。
     A. [ワークフロー入力] を有効にします。
     B. [OCR] で、目的の OCR 機能を有効にします。ナンバー プレート、身分証明書、車両識別番号 (VIN)、タイヤ識別番号 (TIN)、メーター読み取りの中から選択できます。この場合は、[身分証明書] を有効にします。

[ワークフロー入力] および [身分証明書] を有効にします

     C. キーストローク データを使用しない場合は、[キーストローク出力] を無効にします。

キーストローク出力を無効にします

     D. [インテント出力] を有効にして、次の操作を実行します。

  • 手順 1 からアプリでブロードキャスト レシーバを登録するために使用するインテント アクションインテント カテゴリを指定します。この例では次のように指定します。
            • インテント アクション: com.zebra.id_scanning.ACTION
            • インテント カテゴリ: Intent.CATEGORY_DEFAULT

  • [インテント配信] のメカニズムを選択します。この例では、[ブロードキャスト インテント] を選択します。

    インテント出力の構成

2.スキャン結果を受信するようにアプリケーションを設定します

Android アプリケーション (例: IDScanningApp) を作成します。ブロードキャスト レシーバを登録して、ブロードキャスト インテントからスキャン結果を受信します。

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main2);

        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction("com.zebra.id_scanning.ACTION");
        intentFilter.addCategory(Intent.CATEGORY_DEFAULT);
        registerReceiver(broadcastReceiver, intentFilter);
    }

    BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {

        }
    };

3.インテントから文字列データを抽出します

インテントから文字列データを抽出するために、スキャン結果のインテントには、com.symbol.datawedge.data という文字列エクストラ (データ形式は JSON アレイ形式) が含まれます。身分証明書のデータ例を示します。

[
    {
        "group_id":"Uncategorized",
        "imageformat":"YUV",
        "orientation":"90",
        "height":"1080",
        "stride":"1920",
        "size":"4147198",
        "label":"ID card",
        "width":"1920",
        "uri":"content:\/\/com.symbol.datawedge.decode\/18-2-1",
        "data_size":4147198
    },
    {
        "group_id":"Result",
        "string_data":"90",
        "label":"weight",
        "uri":"content:\/\/com.symbol.datawedge.decode\/18-2-2",
        "data_size":2
    },
    {
        "group_id":"Result",
        "string_data":"M",
        "label":"sex",
        "uri":"content:\/\/com.symbol.datawedge.decode\/18-2-3",
        "data_size":1
    },
    {
        "group_id":"Result",
        "string_data":"C91993805",
        "label":"documentNumber",
        "uri":"content:\/\/com.symbol.datawedge.decode\/18-2-5",
        "data_size":9
    },
    {
        "group_id":"Result",
        "string_data":"ADAMS",
        "label":"lastName",
        "uri":"content:\/\/com.symbol.datawedge.decode\/18-2-6",
        "data_size":5
    }
]

ブロードキャスト レシーバで、com.symbol.datawedge.data フィールドのデータを解析して JSONArray オブジェクトにします。JSONArray の各要素は JSONObject です。

BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        Bundle bundle = intent.getExtras();
        String jsonData = bundle.getString("com.symbol.datawedge.data");
        try {
            JSONArray jsonArray = new JSONArray(jsonData);
        }
        catch (Exception ex)
        {
            //Check error
        }
    }
};

JSONArray オブジェクトの要素を反復処理して、各フィールドのデータを抽出します。

  • JSONObject に "string_data" という名前のマッピングがある場合は、この JSONObject に文字列データが含まれていることを意味します。"label" という名前でマッピングされた値を使用して、OCR 機能に基づいて文字列データの型を識別します。結果データの抽出でサポートされているフィールド名については、「OCR 結果出力」を参照してください。
  • JSONObject に "string_data" という名前のマッピングがある場合は、この JSONObject に画像データが含まれていることを意味します。次の手順に進み、画像データを抽出します。

4.インテントから画像データを抽出します

DataWedge コンテンツ プロバイダにアクセスするために、アプリケーション マニフェスト ファイルに次の権限が追加されていることを確認します。

<uses-permission android:name="com.symbol.datawedge.permission.contentprovider" />

[URI] フィールドの値を使用して、DataWedge コンテンツ プロバイダにアクセスする URI を取得します。次に、ContentResolver を使用して URI を渡し、Cursor オブジェクトを取得します。Cursor オブジェクトには、次の 2 つの列があります。

名前 説明
raw_data 画像データを byte[] 形式で格納します
next_data_uri 残りの画像データの取得に使用する URI。残りの画像データがない場合、このフィールドは空になります。

raw_data を読み取りそれを ByteArrayOutputStream オブジェクトに保存します。next_data_uri が空でない場合は、next_data_uri 列に指定されている URI から raw_data を読み取ります。next_data_uri が空になるまで、引き続き raw_data フィールドを読み取って値を ByteArrayOutputStream オブジェクトに格納します。これは、次のように while ループを使用して実行できます。

String uri = jsonObject.getString("uri");
Cursor cursor = getContentResolver().query(Uri.parse(uri),null,null,null);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
if(cursor != null)
{
    cursor.moveToFirst();
    baos.write(cursor.getBlob(cursor.getColumnIndex("raw_data")));
    String nextURI = cursor.getString(cursor.getColumnIndex("next_data_uri"));
    while (nextURI != null && !nextURI.isEmpty())
    {
        Cursor cursorNextData = getContentResolver().query(Uri.parse(nextURI),
                null,null,null);
        if(cursorNextData != null)
        {
            cursorNextData.moveToFirst();
            baos.write(cursorNextData.getBlob(cursorNextData.
                    getColumnIndex("raw_data")));
            nextURI = cursorNextData.getString(cursorNextData.
                    getColumnIndex("next_data_uri"));

            cursorNextData.close();
        }

    }
    cursor.close();
}

すべての値が画像データ用に保存されている場合は、下の表に示す画像出力でサポートされているフィールド名 (例えば「width」、「height」など) によってマップされた値を読み取り、Bitmap オブジェクトを構築します。

画像出力

フィールド名 タイプ 説明
label string サンプルの型を指定する画像ラベル名。「ナンバー プレート」、「身分証明書」、「VIN」、「TIN」、「メーター」
width int 画像の幅 (ピクセル単位)
height int 画像の高さ (ピクセル単位)
size int 画像バッファのサイズ (ピクセル単位)
stride int 画像の 1 行の幅 (ピクセル単位)
imageformat string サポートされている形式: Y8、YUV
注: YUV 形式は NV12 形式として解釈する必要があります。
orientation int 画像バッファの回転角度 (度単位)。値: 0、90、180、270


ImageProcessing クラスの getBitmap() メソッド (下に示す) を使用して、Bitmap オブジェクトを取得します。

int width = 0;
int height = 0;
int stride = 0;
int orientation = 0;
String imageFormat = "";

width = jsonObject.getInt("width");
height = jsonObject.getInt("height");
stride = jsonObject.getInt("stride");
orientation = jsonObject.getInt("orientation");
imageFormat = jsonObject.getString("imageformat");

Bitmap bitmap = ImageProcessing.getInstance().getBitmap(baos.toByteArray(),imageFormat, orientation,stride,width, height);

Class ImageProcessing:

/*
* Copyright (C) 2018-2021 Zebra Technologies Corp
* All rights reserved.
*/
package com.zebra.idscanningapp;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.ImageFormat;
import android.graphics.Matrix;
import android.graphics.Rect;
import android.graphics.YuvImage;

import java.io.ByteArrayOutputStream;

public class ImageProcessing{

    private final String IMG_FORMAT_YUV = "YUV";
    private final String IMG_FORMAT_Y8 = "Y8";

    private static ImageProcessing instance = null;

    public static ImageProcessing getInstance() {

        if (instance == null) {
            instance = new ImageProcessing();
        }
        return instance;
    }

    private ImageProcessing() {
        //Private Constructor
    }

    public Bitmap getBitmap(byte[] data, String imageFormat, int orientation, int stride, int width, int height)
    {
        if(imageFormat.equalsIgnoreCase(IMG_FORMAT_YUV))
        {
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            int uvStride = ((stride + 1)/2)*2;  // calculate UV channel stride to support odd strides
            YuvImage yuvImage = new YuvImage(data, ImageFormat.NV21, width, height, new int[]{stride, uvStride});
            yuvImage.compressToJpeg(new Rect(0, 0, stride, height), 100, out);
            yuvImage.getYuvData();
            byte[] imageBytes = out.toByteArray();
            if(orientation != 0)
            {
                Matrix matrix = new Matrix();
                matrix.postRotate(orientation);
                Bitmap bitmap = BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.length);
                return Bitmap.createBitmap(bitmap, 0 , 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
            }
            else
            {
                return BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.length);
            }
        }
        else if(imageFormat.equalsIgnoreCase(IMG_FORMAT_Y8))
        {
            return convertYtoJPG_CPU(data, orientation, stride, height);
        }

        return null;
    }


    private Bitmap convertYtoJPG_CPU(byte[] data, int orientation, int stride, int height)
    {
        int mLength = data.length;
        int [] pixels = new int[mLength];
        for(int i = 0; i < mLength; i++)
        {
            int p = data[i] & 0xFF;
            pixels[i] = 0xff000000 | p << 16 | p << 8 | p;
        }
        if(orientation != 0)
        {
            Matrix matrix = new Matrix();
            matrix.postRotate(orientation);
            Bitmap bitmap = Bitmap.createBitmap(pixels, stride, height, Bitmap.Config.ARGB_8888);
            return Bitmap.createBitmap(bitmap, 0 , 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
        }
        else
        {
            return Bitmap.createBitmap(pixels, stride, height, Bitmap.Config.ARGB_8888);
        }
    }
}



OCR 結果出力

スキャン結果のインテントには、com.symbol.datawedge.data という文字列エクストラが含まれていて、そこからデータを抽出できます。このセクションでは、各 OCR 機能で使用可能なフィールド名と、身分証明書の場合に使用できる追加のフィールド名について説明します。使用方法については、「インテントから文字列データを抽出する」を参照してください。

OCR 結果

フィールド名 説明
string_data OCR ベースの機能から読み取られたテキスト データ。ナンバー プレート、車両識別番号、タイヤ識別番号、またはメーター。例外は 身分証明書で、多数のフィールド名を返すことができます。以下のセクションを参照してください。
data_size データの長さ


身分証明書

以下の表は、運転免許証、ID カードや健康保険証から読み取ることができるデータ フィールドを示しています。一部のフィールド名は、地域に基づいた文書では異なることがあります。

返されるデータは、身分証明書の内容によって異なります。フィールド名が (以下の表で) 必須に指定されている場合は、一部の身分証明書に存在しない可能性があります。このような場合、フィールド名を照会してもデータは返されません。例:

  • メキシコの投票者 ID (タイプ C) - 生年月日と文書番号が存在しません
  • メキシコの投票者 ID (タイプ G) - 文書番号が存在しません
  • オーストラリアの運転免許証 (NSW) - 名と姓が独立したフィールドとして存在せず、[名前] という単一のフィールドに結合されています。


凡例:

  • O- オプション
  • M- 必須
番号 フィールド名 運転免許証 ID カード 健康保険証
1 additionalInformation N/A O N/A
2 additionalInformation1 N/A O N/A
3 address M N/A N/A
4 age N/A O N/A
5 audit O N/A N/A
6 authority O O M
7 cardAccessNumber N/A O N/A
8 cardNumber O N/A N/A
9 categories O N/A N/A
10 citizenship N/A O N/A
11 cityNumber N/A O N/A
12 class O N/A N/A
13 conditions O N/A N/A
14 country O O N/A
15 dateOfBirth M M M
16 dateOfExpiry O O M
17 dateOfIssue M O N/A
18 dateOfRegistration N/A O N/A
19 divisionNumber N/A O N/A
20 documentDiscriminator O N/A N/A
21 documentNumber M M M
22 duplicate O N/A N/A
23 endorsements O N/A N/A
24 eyes O N/A N/A
25 familyName N/A O N/A
26 fathersName N/A O N/A
27 firstIssued O N/A N/A
28 firstName M M M
29 folio N/A O N/A
30 fullName N/A O N/A
31 hair O N/A N/A
32 高さ O O N/A
33 lastName M M M
34 licenseClass N/A O N/A
35 licenseType N/A O N/A
36 municipalityNumber N/A O N/A
37 name M N/A N/A
38 nationalId N/A O N/A
39 nationality N/A O M
40 office O N/A N/A
41 parentsGivenName N/A O N/A
42 parish O N/A N/A
43 personalNumber O O M
44 placeAndDateOfBirth N/A O N/A
45 placeOfBirth O O N/A
46 previousType O N/A N/A
47 restrictions O N/A N/A
48 revoked O N/A N/A
49 sex O O N/A
50 stateNumber N/A O N/A
51 supportNumber N/A O N/A
52 type O N/A N/A
53 version O N/A N/A
54 verticalNumber O N/A N/A
55 voterId N/A O N/A
56 weight O N/A N/A



関連ガイド: