Die NDK ImageDecoder
API ist eine Standard-API für Android-C/C++-Apps, mit der Bilder direkt decodiert werden können. App-Entwickler müssen die Java APIs (über JNI) oder Bilddecodierungsbibliotheken von Drittanbietern nicht mehr verwenden. Diese API ermöglicht zusammen mit den Codierungsfunktionen im Modul Bitmap Folgendes:
- Native Apps und Bibliotheken können kleiner sein, da sie nicht mehr ihre eigenen Dekodierungsbibliotheken verknüpfen müssen.
- Apps und Bibliotheken profitieren automatisch von Plattformsicherheitsupdates für Dekodierungsbibliotheken.
- Apps können Bilder direkt in den von ihnen bereitgestellten Arbeitsspeicher decodieren. Apps können die Bilddaten dann (falls gewünscht) nachbearbeiten und an OpenGL oder ihren Zeichencode übergeben.
Auf dieser Seite wird beschrieben, wie Sie mit der API ein Bild decodieren.
Verfügbarkeit und Funktionen
Die ImageDecoder
API ist in Apps verfügbar, die auf Android 11 (API-Level 30) oder höher ausgerichtet sind. Die Implementierung befindet sich in den folgenden Dateien:
imagedecoder.h
für den Decoderbitmap.h
für den Encoderlibjnigraphics.so
Die API unterstützt die folgenden Bildformate:
- JPEG
- PNG
- GIF
- WebP
BMP
ICO
WBMP
HEIF
Digitale Negativdateien (über das DNG SDK)
Um alle Verwendungen der decodierten Rohbilder abzudecken, bietet diese API keine Objekte höherer Ebene wie solche, die auf decodierten Bildern im Java-Framework basieren, z. B.:
Drawable
-ObjekteNinePatch
: Wenn in einem codierten Bild vorhanden, werden NinePatch-Chunks ignoriert.- Bitmap-Dichte:
AImageDecoder
führt keine automatische Größenanpassung basierend auf der Bildschirmdichte durch, ermöglicht aber die Dekodierung in eine andere Größe überAImageDecoder_setTargetSize()
. - Animationen: Es wird nur der erste Frame eines animierten GIFs oder einer WebP-Datei decodiert.
Bild decodieren
Die Dekodierung beginnt mit einer Art von Eingabe, die das codierte Bild darstellt.
AImageDecoder
akzeptiert mehrere Eingabetypen:
AAsset
(siehe unten)- Dateideskriptor
- Puffer
Im folgenden Code wird gezeigt, wie ein Bild Asset
aus einer Datei geöffnet, decodiert und dann der Dekoder und das Asset ordnungsgemäß entsorgt werden. Ein Beispiel für das Rendern des decodierten Bilds finden Sie im Beispiel für die Teekanne.
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);