Dekoder obrazów

Interfejs NDK ImageDecoder API zapewnia standardowy interfejs API dla aplikacji na Androida C/C++ do bezpośredniego dekodowania obrazów. Deweloperzy aplikacji – nie nie muszą już używać interfejsów API Javy (przez JNI) lub dekodowania obrazów innych firm. biblioteki. Ten interfejs API, wraz z funkcjami kodowania w Moduł Bitmap, który umożliwia korzystanie z tych funkcji:

  • Aplikacje i biblioteki natywne mogą być mniejsze, ponieważ nie trzeba ich już łączyć własne biblioteki dekodujące.
  • Aplikacje i biblioteki automatycznie korzystają z aktualizacji zabezpieczeń platformy bibliotek do dekodowania.
  • Aplikacje mogą dekodować obrazy bezpośrednio do udostępnianej przez nie pamięci. Aplikacje mogą wtedy dane obrazu (w razie potrzeby) i przekazane do OpenGL lub do rysunków.

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

Dostępność i możliwości

Interfejs API ImageDecoder jest dostępny w aplikacjach kierowanych na Androida 11 (poziom API 30) lub wyższą. 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 przypadki użycia zdekodowanych nieprzetworzonych obrazów, ten interfejs API nie dostarczać obiekty wyższego poziomu, takie jak te stworzone na podstawie zdekodowanych obrazów wewnątrz platformy Java, np.:

  • Drawable obiektów.
  • NinePatch: jeśli znajduje się w zakodowany obraz, fragmenty NinePatch są ignorowane.
  • Gęstość bitmapy: AImageDecoder nie stosuje automatycznego dostosowania rozmiaru na podstawie gęstości ekranu, ale umożliwia dekodowanie do innego rozmiaru 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 potem zniszcz dekoder i zasób. Aby zobaczyć przykład podczas renderowania zdekodowanego obrazu, przykładowy dzbank do herbaty.

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