Dekoder obrazów

NDK ImageDecoder API udostępnia standardowy interfejs API dla aplikacji na Androida w języku C/C++ do bezpośredniego dekodowania obrazów. Deweloperzy aplikacji nie muszą już używać interfejsów API Javy (przez JNI) ani bibliotek do dekodowania obrazów innych firm. Ten interfejs wraz z funkcjami kodowania w module Bitmap umożliwia korzystanie z:

  • Aplikacje i biblioteki natywne mogą być mniejsze, ponieważ nie muszą już łączyć własnych bibliotek dekodowania.
  • Aplikacje i biblioteki automatycznie korzystają z aktualizacji zabezpieczeń platformy do dekodowania bibliotek.
  • Aplikacje mogą dekodować obrazy bezpośrednio do udostępnianej przez nie pamięci. Aplikacje mogą następnie przetworzyć dane obrazu (w razie potrzeby) i przekazać je do OpenGL lub do swojego kodu rysowania.

Na tej stronie dowiesz się, jak dekodować obraz za pomocą interfejsu API.

Dostępność i możliwości

Interfejs ImageDecoder API jest dostępny w aplikacjach kierowanych na Androida 11 (poziom API 30) lub nowszego. Implementacja znajduje się w tych plikach:

  • imagedecoder.h dla dekodera
  • bitmap.h dla kodera
  • libjnigraphics.so

Interfejs API obsługuje te formaty obrazów:

  • JPEG
  • PNG
  • GIF
  • WebP
  • BMP

  • ICO

  • WBMP

  • HEIF

  • Cyfrowe wykluczenia (przez pakiet SDK DNG)

Aby uwzględnić wszystkie zastosowania zdekodowanych nieprzetworzonych obrazów, ten interfejs API nie udostępnia obiektów wyższego poziomu, takich jak te, które zostały utworzone na podstawie zdekodowanych obrazów wewnątrz platformy Java, takich jak:

  • Drawable obiektów.
  • NinePatch: jeśli występuje w zakodowanym obrazie, fragmenty NinePatch są ignorowane.
  • Gęstość bitmapy: AImageDecoder nie automatycznie dostosowuje rozmiaru na podstawie gęstości ekranu, ale umożliwia dekodowanie do innego rozmiaru za pomocą AImageDecoder_setTargetSize().
  • Animacje: dekoduje tylko pierwszą klatkę animowanego pliku GIF lub WebP.

Dekodowanie obrazu

Dekodowanie rozpoczyna się od wprowadzenia pewnych danych, które reprezentują zakodowany obraz. AImageDecoder akceptuje wiele typów danych wejściowych:

  • AAsset (widoczne poniżej)
  • Deskryptor pliku
  • Bufor

Ten kod pokazuje, jak otworzyć obraz Asset z pliku, zdekodować go, a następnie prawidłowo usunąć dekoder i zasób. Przykład renderowania zdekodowanego obrazu znajdziesz w przykładzie przedstawiającym czajnik.

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