С помощью API описания изображений GenAI из ML Kit вы можете создавать краткие описания содержимого изображений. Это может быть полезно в следующих случаях:
- Генерация названий изображений
- Создание альтернативного текста (alt-текста), помогающего пользователям со слабым зрением лучше понимать содержание изображений.
- Использование сгенерированных описаний в качестве метаданных для облегчения поиска и организации изображений пользователями
- Использование кратких описаний изображений, когда пользователь не может смотреть на экран, например, когда он ведет машину или слушает подкаст.
Ключевые возможности
- Вернуть краткое описание для входного изображения
Примеры результатов
Вход | Выход |
![]() | Маленький зеленый робот-андроид, напоминающий по дизайну кактус, сидит на черной поверхности. |
![]() | Маленькая белая собака с черным носом и розовым языком бежит по травянистому полю с мостом на заднем плане. |
Начиная
Чтобы начать работу с API описания изображений GenAI, добавьте эту зависимость в файл сборки вашего проекта.
implementation("com.google.mlkit:genai-image-description:1.0.0-beta1")
Чтобы интегрировать API описания изображений в своё приложение, сначала нужно получить клиент ImageDescriber
. Затем необходимо проверить состояние необходимых функций модели на устройстве и загрузить модель, если она ещё не загружена. После подготовки входных данных изображения в запросе ImageDescriptionRequest
выполните вывод с помощью клиента для получения текста описания изображения. После этого не забудьте закрыть клиент, чтобы освободить ресурсы.
Котлин
// 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()
Ява
// 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();
Поддерживаемые функции и ограничения
API описания изображений GenAI поддерживает английский язык, а в будущем планируется добавить поддержку других языков. API возвращает краткое описание изображения.
Доступность конкретной конфигурации функций (указанной параметром ImageDescriberOptions
) может различаться в зависимости от конфигурации конкретного устройства и моделей, загруженных на устройство.
Самый надёжный способ для разработчиков убедиться, что требуемая функция API поддерживается на устройстве с запрошенным параметром ImageDescriberOptions
, — это вызвать метод checkFeatureStatus()
. Этот метод предоставляет точную информацию о доступности функции на устройстве во время выполнения.
Распространенные проблемы с настройкой
API ML Kit GenAI используют приложение Android AICore для доступа к Gemini Nano. Если устройство только что настроено (включая сброс настроек) или приложение AICore только что сброшено (например, для удаления данных, удаления и последующей переустановки), приложению AICore может не хватить времени для завершения инициализации (включая загрузку последних конфигураций с сервера). В результате API ML Kit GenAI могут работать некорректно. Ниже приведены распространённые сообщения об ошибках настройки и способы их устранения:
Пример сообщения об ошибке | Как обращаться |
Произошла ошибка AICore с типом ошибки 4-CONNECTION_ERROR и кодом ошибки 601-BINDING_FAILURE: Службе AICore не удалось выполнить привязку. | Это может произойти, если вы устанавливаете приложение с помощью API GenAI из ML Kit сразу после настройки устройства или если AICore удаляется после установки приложения. Обновление AICore и его переустановка должны исправить проблему. |
Произошла ошибка AICore с типом ошибки 3-PREPARATION_ERROR и кодом ошибки 606-FEATURE_NOT_FOUND: Функция ... недоступна. | Это может произойти, если AICore не завершил загрузку последних конфигураций. При подключении устройства к интернету обновление обычно занимает от нескольких минут до нескольких часов. Перезапуск устройства может ускорить обновление. Обратите внимание: если загрузчик устройства разблокирован, вы также увидите эту ошибку — этот API не поддерживает устройства с разблокированными загрузчиками. |
Ошибка AICore: тип ошибки 1-DOWNLOAD_ERROR и код ошибки 0-UNKNOWN: Функция ... завершилась неудачей со статусом ошибки 0 и ошибкой esz: UNAVAILABLE: Не удалось разрешить хост ... | Сохраните сетевое подключение, подождите несколько минут и повторите попытку. |