Interfejs NDK ImageDecoder
API udostępnia standardowy interfejs API dla aplikacji na Androida w językach C/C++, który umożliwia bezpośrednie dekodowanie obrazów. Deweloperzy aplikacji nie muszą już korzystać z interfejsów API Java (za pomocą JNI) ani bibliotek dekodowania obrazów innych firm. Ten interfejs API wraz z funkcjami kodowania w module Bitmap umożliwia:
- 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 w bibliotekach dekodowania.
- Aplikacje mogą dekodować obrazy bezpośrednio w pamięci, którą udostępniają. Aplikacje mogą następnie przetwarzać dane obrazu (w razie potrzeby) i przekazywać je do OpenGL lub kodu rysowania.
Na tej stronie opisujemy, jak używać interfejsu API do dekodowania obrazu.
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 dekoderabitmap.h
dla koderalibjnigraphics.so
Interfejs API obsługuje te formaty obrazów:
- JPEG
- PNG
- GIF
- WebP
BMP
ICO
WBMP
HEIF
Cyfrowe negatywy (za pomocą pakietu DNG SDK)
Aby uwzględnić wszystkie zastosowania zdekodowanych obrazów w formacie RAW, ten interfejs API nie udostępnia obiektów wyższego poziomu, takich jak te, które są tworzone na podstawie zdekodowanych obrazów w ramach platformy Java, np.:
Drawable
obiektów.NinePatch
: Jeśli w zakodowanym obrazie występują fragmenty NinePatch, są one ignorowane.- Gęstość mapy bitowej:
AImageDecoder
nie dostosowuje automatycznie 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 danych wejściowych reprezentujących zakodowany obraz.
AImageDecoder
akceptuje wiele typów danych wejściowych:
AAsset
(jak poniżej)- Deskryptor pliku
- Bufor
Poniższy kod pokazuje, jak otworzyć obrazAsset
z pliku, zdekodować go, a następnie prawidłowo usunąć dekoder i zasób. Przykład renderowania zdekodowanego obrazu znajdziesz w przykładzie z czajnikiem.
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);