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

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
  • гифка
  • ВебП
  • БМП

  • ICO

  • ВБМП

  • ХИФ

  • Цифровые негативы (через 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);