GenAI Image Description API

With ML Kit's GenAI Image Description API, you can generate short content descriptions for images. This can be useful in the following use cases:

  • Generating titles of images
  • Generating alternative text (alt text) to help visually impaired users better understand the content of images
  • Using generated descriptions as metadata to help users search or organize images
  • Utilizing short descriptions of images when the user is unable to look at their screen, such as when they are driving or listening to a podcast

Key capabilities

  • Return a short description for an input image

Example results

Input Output
A small, green Android robot with a cactus-like design sits on
             a black surface. A small, green Android robot with a cactus-like design sits on a black surface.
A small, white dog with a black nose and pink tongue runs
                across a grassy field with a bridge in the background. A small, white dog with a black nose and pink tongue runs across a grassy field with a bridge in the background.

Getting Started

To get started with the GenAI Image Description API, add this dependency to your project's build file.

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

To integrate the Image Description API into your app, you will begin by getting an ImageDescriber client. You must then check the status of the necessary on-device model features and download the model if it isn't already on the device. After preparing your image input in an ImageDescriptionRequest , you run the inference using the client to obtain the image description text, and finally, remember to close the client to release resources.

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 
 (); 
 

Supported features and limitations

The GenAI Image Description API supports English, with support for more languages to be added in the future. The API returns one short description of the image.

Availability of the specific feature configuration (specified by ImageDescriberOptions ) may vary depending on the particular device's configuration and the models that have been downloaded to the device.

The most reliable way for developers to ensure that the intended API feature is supported on a device with the requested ImageDescriberOptions is to call the checkFeatureStatus() method. This method provides the definitive status of feature availability on the device at runtime.

Common setup issues

ML Kit GenAI APIs rely on the Android AICore app to access Gemini Nano. When a device is just setup (including reset), or the AICore app is just reset (e.g. clear data, uninstalled then reinstalled), the AICore app may not have enough time to finish initialization (including downloading latest configurations from server). As a result, the ML Kit GenAI APIs may not function as expected. Here are the common setup error messages you may see and how to handle them:

Example error message How to handle
AICore failed with error type 4-CONNECTION_ERROR and error code 601-BINDING_FAILURE: AICore service failed to bind. This could happen when you install the app using ML Kit GenAI APIs immediately after device setup or when AICore is uninstalled after your app is installed. Updating AICore app then reinstalling your app should fix it.
AICore failed with error type 3-PREPARATION_ERROR and error code 606-FEATURE_NOT_FOUND: Feature ... is not available. This could happen when AICore hasn't finished downloading the latest configurations. When the device is connected to the internet, it usually takes a few minutes to a few hours to update. Restarting the device can speed up the update.

Note that if the device's bootloader is unlocked, you'll also see this error—this API does not support devices with unlocked bootloaders.
AICore failed with error type 1-DOWNLOAD_ERROR and error code 0-UNKNOWN: Feature ... failed with failure status 0 and error esz: UNAVAILABLE: Unable to resolve host ... Keep network connection, wait for a few minutes and retry.
Create a Mobile Website
View Site in Mobile | Classic
Share by: