GenAI Image Description API

ML Kit の GenAI Image Description API を使用すると、画像の短いコンテンツの説明を生成できます。これは、次のようなユースケースで役立ちます。

  • 画像のタイトルの生成
  • 視覚障がいのあるユーザーが画像の内容をよりよく理解できるように、代替テキスト(alt テキスト)を生成します。
  • 生成された説明をメタデータとして使用して、ユーザーが画像を検索または整理できるようにする
  • ユーザーが画面を見ることができない状況(運転中やポッドキャストを聴いているときなど)で、画像の簡単な説明を活用する

主な機能

  • 入力画像の簡単な説明を返す

検索結果の例

入力 出力
サボテンのようなデザインの小さな緑色の Android ロボットが黒い表面に置かれている。 サボテンのようなデザインの小さくて緑色の Android ロボットが黒い表面に置かれている。
黒い鼻とピンクの舌を持つ小さな白い犬が、背景に橋がある芝生のあるフィールドを走っています。 黒い鼻とピンクの舌を持つ小さな白い犬が、背景に橋がある芝生のあるフィールドを走っています。

スタートガイド

GenAI Image Description API の使用を開始するには、プロジェクトのビルドファイルに次の依存関係を追加します。

implementation("com.google.mlkit:genai-image-description:1.0.0-beta1")

Image Description API をアプリに統合するには、まず ImageDescriber クライアントを取得します。次に、必要なデバイス上のモデル機能のステータスを確認し、デバイスにまだモデルがない場合はそのモデルをダウンロードする必要があります。ImageDescriptionRequest で画像入力を準備したら、クライアントを使用して推論を実行して画像の説明テキストを取得します。最後に、クライアントを閉じてリソースを解放してください。

Kotlin

// Create an image describer
val options = ImageDescriberOptions.builder(context).build()
val imageDescriber = ImageDescription.getClient(options)

suspend fun prepareAndStartImageDescription(
    bitmap: Bitmap
) {
  // Check feature availability, status will be one of the following:
  // UNAVAILABLE, DOWNLOADABLE, DOWNLOADING, AVAILABLE
  val featureStatus = imageDescriber.checkFeatureStatus().await()

  if (featureStatus == FeatureStatus.DOWNLOADABLE) {
      // Download feature if necessary.
      // If downloadFeature is not called, the first inference request
      // will also trigger the feature to be downloaded if it's not
      // already downloaded.
      imageDescriber.downloadFeature(object : DownloadCallback {
          override fun onDownloadStarted(bytesToDownload: Long) { }

          override fun onDownloadFailed(e: GenAiException) { }

          override fun onDownloadProgress(totalBytesDownloaded: Long) {}

          override fun onDownloadCompleted() {
              startImageDescriptionRequest(bitmap, imageDescriber)
          }
      })
  } else if (featureStatus == FeatureStatus.DOWNLOADING) {
      // Inference request will automatically run once feature is
      // downloaded.
      // If Gemini Nano is already downloaded on the device, the
      // feature-specific LoRA adapter model will be downloaded
      // very quickly. However, if Gemini Nano is not already
      // downloaded, the download process may take longer.
      startImageDescriptionRequest(bitmap, imageDescriber)
  } else if (featureStatus == FeatureStatus.AVAILABLE) {
      startImageDescriptionRequest(bitmap, imageDescriber)
  }
}

fun startImageDescriptionRequest(
    bitmap: Bitmap,
    imageDescriber: ImageDescriber
) {
    // Create task request
    val imageDescriptionRequest = ImageDescriptionRequest
        .builder(bitmap)
        .build()
}

  // Run inference with a streaming callback
  val imageDescriptionResultStreaming =
      imageDescriber.runInference(imageDescriptionRequest) { outputText ->
          // Append new output text to show in UI
          // This callback is called incrementally as the description
          // is generated
      }

  // You can also get a non-streaming response from the request
  // val imageDescription = imageDescriber.runInference(
  //        imageDescriptionRequest).await().description
}

// Be sure to release the resource when no longer needed
// For example, on viewModel.onCleared() or activity.onDestroy()
imageDescriber.close()

Java

// Create an image describer
ImageDescriberOptions options = ImageDescriberOptions.builder(context).build();
ImageDescriber imageDescriber = ImageDescription.getClient(options);

void prepareAndStartImageDescription(
      Bitmap bitmap
) throws ExecutionException, InterruptedException {
  // Check feature availability, status will be one of the following:
  // UNAVAILABLE, DOWNLOADABLE, DOWNLOADING, AVAILABLE
  try {
      int featureStatus = imageDescriber.checkFeatureStatus().get();
      if (featureStatus == FeatureStatus.DOWNLOADABLE) {
          // Download feature if necessary.
          // If downloadFeature is not called, the first inference request
          // will also trigger the feature to be downloaded if it's not
          // already downloaded.
          imageDescriber.downloadFeature(new DownloadCallback() {
              @Override
              public void onDownloadCompleted() {
                  startImageDescriptionRequest(bitmap, imageDescriber);
              }

              @Override
              public void onDownloadFailed(GenAIException e) {}

              @Override
              public void onDownloadProgress(long totalBytesDownloaded) {}

              @Override
              public void onDownloadStarted(long bytesDownloaded) {}
          });
      } else if (featureStatus == FeatureStatus.DOWNLOADING) {
          // Inference request will automatically run once feature is
          // downloaded.
          // If Gemini Nano is already downloaded on the device, the
          // feature-specific LoRA adapter model will be downloaded
          // very quickly. However, if Gemini Nano is not already
          // downloaded, the download process may take longer.
          startImageDescriptionRequest(bitmap, imageDescriber);
      } else if (featureStatus == FeatureStatus.AVAILABLE) {
          startImageDescriptionRequest(bitmap, imageDescriber);
      }
  } catch (ExecutionException | InterruptedException e) {
      e.printStackTrace();
  }
}

void startImageDescriptionRequest(
     Bitmap bitmap,
     ImageDescriber imageDescriber
) {
  // Create task request
  ImageDescriptionRequest imageDescriptionRequest =
          ImageDescriptionRequest.builder(bitmap).build();

  // Start image description request with streaming response
  imageDescriber.runInference(imageDescriptionRequest, newText -> {
      // Append new output text to show in UI
      // This callback is called incrementally as the description
      // is generated
  });

  // You can also get a non-streaming response from the request
  // String imageDescription = imageDescriber.runInference(
  //        imageDescriptionRequest).get().getDescription();
}

// Be sure to release the resource when no longer needed
// For example, on viewModel.onCleared() or activity.onDestroy()
imageDescriber.close();

サポートされている機能と制限事項

GenAI Image Description API は英語をサポートしており、今後、サポートする言語を追加する予定です。API は、画像の簡単な説明を 1 つ返します。

特定の機能構成(ImageDescriberOptions で指定)の可用性は、特定のデバイスの構成と、デバイスにダウンロードされているモデルによって異なる場合があります。

デベロッパーが目的の API 機能が、リクエストされた ImageDescriberOptions を持つデバイスでサポートされていることを確認する最も確実な方法は、checkFeatureStatus() メソッドを呼び出すことです。このメソッドは、実行時にデバイスで利用可能な機能の確定ステータスを提供します。

セットアップに関する一般的な問題

ML Kit の生成 AI API は、Android AICore アプリを使用して Gemini Nano にアクセスします。デバイスのセットアップ(リセットを含む)が完了したばかりの場合や、AICore アプリがリセットされたばかりの場合(データの消去、アンインストール、再インストールなど)、AICore アプリが初期化(サーバーから最新の構成のダウンロードなど)を完了するまでに時間がかかることがあります。その結果、ML Kit GenAI API が想定どおりに機能しない可能性があります。セットアップ時に表示される一般的なエラー メッセージとその対処方法は次のとおりです。

エラー メッセージの例 対応方法
AICore がエラータイプ 4-CONNECTION_ERROR とエラーコード 601-BINDING_FAILURE で失敗しました。AICore サービスがバインディングに失敗しました。 これは、デバイスのセットアップ直後に ML Kit GenAI API を使用してアプリをインストールした場合や、アプリのインストール後に AICore がアンインストールされた場合に発生する可能性があります。AICore アプリを更新してからアプリを再インストールすると、問題は解決するはずです。
AICore がエラータイプ 3-PREPARATION_ERROR とエラーコード 606-FEATURE_NOT_FOUND で失敗しました。機能... は使用できません。 これは、AICore が最新の構成のダウンロードを完了していない場合に発生することがあります。ネットワーク接続を維持し、数分~数時間待ちます。

デバイスのブートローダーがロック解除されている場合も、このエラーが表示されます。この API は、ブートローダーがロック解除されているデバイスをサポートしていません。
AICore がエラータイプ 1-DOWNLOAD_ERROR で失敗し、エラーコード 0-UNKNOWN: Feature ... が失敗し、失敗ステータス 0 とエラー esz: UNAVAILABLE: Unable to resolve host ... が返されました ネットワーク接続を維持し、数分待ってから再試行します。