Interfejs NDK ImageDecoder
API udostępnia standardowy interfejs API dla aplikacji w języku C/C++ na Androida do bezpośredniego dekodowania obrazów. Deweloperzy aplikacji nie muszą już korzystać z interfejsów Java API (przez JNI) ani bibliotek do dekodowania obrazów innych firm. Ten interfejs API wraz z funkcjami kodowania w module Bitmap umożliwia:
- Natywne aplikacje i biblioteki mogą być mniejsze, ponieważ nie muszą już łączyć własnych bibliotek dekodowania.
- Aplikacje i biblioteki automatycznie korzystają z aktualizacji zabezpieczeń platformy bibliotek do dekodowania.
- Aplikacje mogą dekodować obrazy bezpośrednio do zapewnianej przez nie pamięci. Aplikacje mogą następnie przetworzyć dane obrazu (w razie potrzeby) i przekazać je do OpenGL lub do swojego kodu.
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 nowszy. Implementacja znajduje się w tych plikach:
imagedecoder.h
– dekoderbitmap.h
dla koderalibjnigraphics.so
Interfejs API obsługuje te formaty obrazów:
- JPEG
- PNG
- GIF
- WebP
BMP
ICO
WBMP
HEIF
Cyfrowe wykluczające dane (za pomocą DNG SDK)
Aby pokryć wszystkie przypadki użycia zdekodowanych nieprzetworzonych obrazów, ten interfejs API nie udostępnia obiektów wyższego poziomu, takich jak obiekty utworzone na zdekodowanych obrazach w ramach platformy Java, takie jak:
Drawable
obiekty.NinePatch
: jeśli ten obraz znajduje się 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 danych wejściowych reprezentujących zakodowany obraz.
Funkcja AImageDecoder
akceptuje różne rodzaje danych wejściowych:
AAsset
(na ilustracji poniżej)- Deskryptor pliku
- Bufor
Poniższy kod pokazuje, jak otworzyć obraz Asset
z pliku, zdekodować go, a następnie prawidłowo pozbyć się dekodera i zasobu. Przykład renderowania zdekodowanego obrazu znajdziesz w przykładzie czajnika.
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);