- はじめに
- ML Kit とは
- ML Kit Document Scanner API とは
- 主なクラスについて
- GmsDocumentScannerOptions (オプション)
- GmsDocumentScanning (スキャナーの開始)
- GmsDocumentScanningResult (結果処理)
- まとめ
- 余談
はじめに
トモニテでAndroid開発を担当している岡田です。
先日、ML Kit Document Scanner API のベータ版がリリースされました。
公式ドキュメントやサンプルアプリを参考に、今回はAndroidでの実装方法・内容をご紹介したいと思います。
以下に参考にしたサイトのリンクを示します。是非覗いてみてください。
android-developers.googleblog.com
ML Kit とは
Googleの機械学習の機能を、Android/iOSアプリとして提供するモバイルSDKです。
例えば顔検出やバーコードスキャンなどの機能を簡単に実装することができます。
ML Kit Document Scanner API とは
紙の資料をカメラでスキャンして、デジタル資料として読み込むことができる、ドキュメントスキャナーSDKのAPIです。
用意されたスキャナーは自動キャプチャ・切り抜き・自動回転検出機能だけでなく、フィルター機能など編集もできます。
つまり、すごいリッチなスキャナーを簡単に実装できるということです。
スキャナーの使用感については公式のサンプルアプリでご確認ください。
実装の簡単な流れは以下の通りです。
- スキャナーのオプションを決める
- スキャナーを呼び出す
- スキャナーから結果を取得する
主なクラスについて
主に以下の3つのクラスで構成されています。
- GmsDocumentScannerOptions
- GmsDocumentScanning
- GmsDocumentScanningResult
それぞれ名前の通り、スキャナーのオプション、スキャン開始、スキャン結果に関するクラスになっています。
これらについて、実際に確認してみたいと思います。
GmsDocumentScannerOptions (オプション)
GmsDocumentScannerOptions
でスキャナーに関してのオプションを設定できます。
公式ドキュメントのコードでは、以下のように紹介されています。
val options = GmsDocumentScannerOptions.Builder() .setGalleryImportAllowed(false) // フォトギャラリーからのインポートの可否 .setPageLimit(2) // 最大ページ枚 .setResultFormats(RESULT_FORMAT_JPEG, RESULT_FORMAT_PDF) // 結果のフォーマット .setScannerMode(SCANNER_MODE_FULL) // スキャナのモード .build()
設定できるオプションは以下の通りです。
- スキャナーのモード
- 最大ページ枚
- 結果のフォーマット
- フォトギャラリーからのインポートの可否
それぞれ見ていきます。
スキャナーのモード
setScannerMode()
を用いて、スキャナーの設定ができます。
現段階では3種類のモードが要されています。
public static final int SCANNER_MODE_BASE = 3; public static final int SCANNER_MODE_BASE_WITH_FILTER = 2; public static final int SCANNER_MODE_FULL = 1;
SCANNER_MODE_BASE
基本的な編集機能(ページの切り抜き、回転、並べ替えなど)が使用できます。
SCANNER_MODE_BASE_WITH_FILTER
SCANNER_MODE_BASEモードに画像フィルタ(グレースケール、自動画像補正など)が追加されます。
SCANNER_MODE_FULL(デフォルト)
SCANNER_MODE_BASE_WITH_FILTERモードの機能に加えて画像クリーニング機能(汚れや指の消去など)が追加されます。
最大ページ数
setPageLimit()
を用いて、最大のページ数を指定できます。int型
で指定します。
以下は最大ページ数を2とした場合のスクリーンショットです。最大数に達すると、ページを追加する "+" アイコンが出ないことがわかると思います。
フォトギャラリーからのインポートの可否
フォトギャラリーからのインポートの可否を設定できます。
setGalleryImportAllowed()
を用い、Booleanで指定します。
結果のフォーマット
setResultFormats()
を用いて、出力結果のフォーマットを指定できます。
現段階では、JPEGかPDF、またはその両方を選択できるようです。
public static final int RESULT_FORMAT_JPEG = 101; public static final int RESULT_FORMAT_PDF = 102;
GmsDocumentScanning (スキャナーの開始)
スキャナーはGmsDocumentScanning
を用いて、以下のように記述できます。
コードは公式のドキュメントとサンプルを参考にしました。
GmsDocumentScanning.getClient(options) // optionsは先ほど紹介したGmsDocumentScannerOptions .getStartScanIntent(activity) .addOnSuccessListener { intentSender -> scannerLauncher.launch(IntentSenderRequest.Builder(intentSender).build()) } .addOnFailureListener { // 失敗した際の処理 }
メソッドチェーンでわかりにくいので、順を追って説明します。
はじめに、GmsDocumentScanning
のgetClient()
を呼び出します。
getClient()
はGmsDocumentScannerOptions
を引数にとり、GmsDocumentScanner
を返します。
public final class GmsDocumentScanning { @androidx.annotation.NonNull public static com.google.mlkit.vision.documentscanner.GmsDocumentScanner getClient(@androidx.annotation.NonNull com.google.mlkit.vision.documentscanner.GmsDocumentScannerOptions options) { /* compiled code */ } private GmsDocumentScanning() { /* compiled code */ } }
返ってくるGmsDocumentScanner
はInterfaceです。getStartScanIntent()
というメソッドが用意されています。
こちらはActivity
を引数にとり、Task<IntentSender>
を返します。
Task
が返されるので、addOnSuccessListener
とaddOnFailureListener
が使えます。
成功時にIntentSender
が返ってきます。IntentSender
はスキャナーを起動するために使用します。
public interface GmsDocumentScanner extends com.google.android.gms.common.api.OptionalModuleApi { @androidx.annotation.NonNull com.google.android.gms.tasks.Task<android.content.IntentSender> getStartScanIntent(@androidx.annotation.NonNull android.app.Activity activity); }
scannerLauncher
は後述する、ActivityResultLauncher<IntentSenderRequest>
型の変数です。
こちらは終了したActivityの結果を受け取り、処理します。
GmsDocumentScanningResult (結果処理)
GmsDocumentScanningResult
を用いて、結果を処理できます。
公式ドキュメントにて、以下のように記述されています。
val scannerLauncher = registerForActivityResult(StartIntentSenderForResult()) { result -> { if (result.resultCode == RESULT_OK) { val result = GmsDocumentScanningResult.fromActivityResultIntent(result.data) // ここで結果を受け取る result.getPages()?.let { pages -> for (page in pages) { val imageUri = pages.get(0).getImageUri() // imageUriを用いた処理 } } result.getPdf()?.let { pdf -> val pdfUri = pdf.getUri() val pageCount = pdf.getPageCount() // pdfUriやpageCountを用いた処理 } } } }
GmsDocumentScanningResult
のfromActivityResultIntent()
を用いて、結果を受け取ります。
Intent
を引数に取り、GmsDocumentScanningResult
として返してくれます。
@androidx.annotation.Nullable public static com.google.mlkit.vision.documentscanner.GmsDocumentScanningResult fromActivityResultIntent(@androidx.annotation.Nullable android.content.Intent data) { /* compiled code */ }
返されるGmsDocumentScanningResult
ですが、Page
とPdf
を持っています。
public abstract class GmsDocumentScanningResult implements android.os.Parcelable { ... public static abstract class Page implements android.os.Parcelable { @androidx.annotation.NonNull public abstract android.net.Uri getImageUri(); public Page() { /* compiled code */ } } public static abstract class Pdf implements android.os.Parcelable { public abstract int getPageCount(); @androidx.annotation.NonNull public abstract android.net.Uri getUri(); public Pdf() { /* compiled code */ } } }
現時点でpage
は画像のUri
、Pdf
はページ数とUri
を取得できるようです。
それぞれ結果に合わせて、処理を記述できます。
説明については、以上になります。
まとめ
ML Kit Document Scanner API を用いると、簡単に高品質なドキュメントスキャナーが実装できました。
実装の簡単な流れは以下の通りです。
- スキャナーのオプションを決める
- スキャナーを呼び出す
- スキャナーから結果を取得する
余談
未実装のキャプチャーモード
com.google.mlkit.vision.documentscanner.GmsDocumentScannerOptions のコードには CaptureMode
なるものが存在しました。
public static final int CAPTURE_MODE_AUTO = 1; public static final int CAPTURE_MODE_MANUAL = 2;
現在はオートのみだが、今後はマニュアルで選択できるような機能が追加されるかもしれない……?
アップデートが楽しみです。今後も追っていきたいと思います!