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

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
  • ПНГ
  • GIF
  • ВебП
  • БМП

  • ИКО

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