Декодер изображений

API NDK ImageDecoder предоставляет стандартный API для Android-приложений на C/C++ для прямого декодирования изображений. Разработчикам приложений больше не нужно использовать API Java (через JNI) или сторонние библиотеки декодирования изображений. Этот API, наряду с функциями кодирования в модуле Bitmap , обеспечивает следующее:

  • Нативные приложения и библиотеки могут стать меньше, поскольку им больше не нужно подключать собственные библиотеки декодирования.
  • Приложения и библиотеки автоматически получают преимущества от обновлений безопасности платформы для декодирующих библиотек.
  • Приложения могут декодировать изображения непосредственно в предоставленную ими память. При необходимости приложения могут выполнить постобработку данных изображения и передать их в OpenGL или свой код отрисовки.

На этой странице описывается, как использовать API для декодирования изображения.

Доступность и возможности

API ImageDecoder доступен в приложениях для Android 11 (API уровня 30) и выше. Реализация находится в следующих файлах:

  • imagedecoder.h для декодера
  • bitmap.h для кодировщика
  • libjnigraphics.so

API поддерживает следующие форматы изображений:

  • JPEG
  • PNG
  • GIF
  • WebP
  • БМП

  • ICO

  • WBMP

  • ХЕИФ

  • Цифровые негативы (через DNG SDK)

Чтобы охватить все варианты использования декодированных необработанных изображений, этот API не предоставляет объекты более высокого уровня, подобные тем, что построены на основе декодированных изображений внутри платформы Java, например:

  • Drawable объекты .
  • NinePatch : если фрагменты NinePatch присутствуют в кодированном изображении, они игнорируются.
  • Плотность растрового изображения : AImageDecoder не выполняет автоматическую настройку размера на основе плотности экрана, но позволяет декодировать изображение в другой размер с помощью AImageDecoder_setTargetSize() .
  • Анимация: декодирует только первый кадр анимированного файла GIF или WebP.

Декодировать изображение

Декодирование начинается с ввода, представляющего собой закодированное изображение. AImageDecoder принимает несколько типов входных данных:

  • AAsset (показано ниже)
  • Файловый дескриптор
  • Буфер

Следующий код показывает, как открыть Asset из файла, декодировать его, а затем правильно удалить декодер и актив. Пример рендеринга декодированного изображения см. в примере с чайником .

AAssetManager* nativeManager = AAssetManager_fromJava(env, jAssets);
const char* file = // Filename
AAsset* asset = AAssetManager_open(nativeManager, file, AASSET_MODE_STREAMING);
AImageDecoder* decoder;
int result = AImageDecoder_createFromAAsset(asset, &decoder);
if (result != ANDROID_IMAGE_DECODER_SUCCESS) {
  // An error occurred, and the file could not be decoded.
}

const AImageDecoderHeaderInfo* info = AImageDecoder_getHeaderInfo(decoder);
int32_t width = AImageDecoderHeaderInfo_getWidth(info);
int32_t height = AImageDecoderHeaderInfo_getHeight(info);
AndroidBitmapFormat format =
       (AndroidBitmapFormat) AImageDecoderHeaderInfo_getAndroidBitmapFormat(info);
size_t stride = AImageDecoder_getMinimumStride(decoder);  // Image decoder does not
                                                          // use padding by default
size_t size = height * stride;
void* pixels = malloc(size);

result = AImageDecoder_decodeImage(decoder, pixels, stride, size);
if (result != ANDROID_IMAGE_DECODER_SUCCESS) {
  // An error occurred, and the file could not be decoded.
}

// We’re done with the decoder, so now it’s safe to delete it.
AImageDecoder_delete(decoder);

// The decoder is no longer accessing the AAsset, so it is safe to
// close it.
AAsset_close(asset);

// Draw the pixels somewhere

// Free the pixels when done drawing with them
free(pixels);