Die NDK-API ImageDecoder bietet eine Standard-API für Android-C/C++-Apps, mit der Bilder direkt decodiert werden können. App-Entwickler müssen nicht mehr die Java APIs (über JNI) oder Bilddecodierungsbibliotheken von Drittanbietern verwenden. Diese API ermöglicht zusammen mit den Codierungsfunktionen im Bitmap-Modul Folgendes:
- Systemeigene Apps und Bibliotheken können kleiner sein, da sie keine eigenen Decodierungsbibliotheken mehr verknüpfen müssen.
- Apps und Bibliotheken profitieren automatisch von den Sicherheitsupdates der Plattform für Decodierungsbibliotheken.
- 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 die API zum Decodieren eines Bildes verwenden.
Verfügbarkeit und Funktionen
Die ImageDecoder API ist für Apps verfügbar, die auf Android 11 (API-Level 30) oder höher ausgerichtet sind. Die Implementierung befindet sich in den folgenden Dateien:
imagedecoder.hfür den Decoderbitmap.hfür den Encoderlibjnigraphics.so
Die API unterstützt die folgenden Bildformate:
- JPEG
- PNG
- GIF
- WebP
BMP
ICO
WBMP
HEIF
Digitale Negative (über das DNG SDK)
Um alle Verwendungen der decodierten Rohbilder abzudecken, stellt diese API keine übergeordneten Objekte bereit, wie sie im Java-Framework auf decodierten Bildern aufbauen, z. B.:
Drawable-Objekte.NinePatch: Wenn in einem codierten Bild vorhanden, werden NinePatch-Blöcke ignoriert.- Bitmap-Dichte:
AImageDecodernimmt keine automatische Größenanpassung basierend auf der Pixeldichte des Bildschirms vor, ermöglicht aber die Decodierung in eine andere Größe überAImageDecoder_setTargetSize(). - Animationen: Es wird nur der erste Frame einer animierten GIF- oder WebP-Datei decodiert.
Bild decodieren
Die Decodierung beginnt mit einer Eingabe, die das codierte Bild darstellt.
AImageDecoder akzeptiert mehrere Eingabetypen:
AAsset(siehe unten)- Dateideskriptor
- Puffer
Der folgende Code zeigt, wie ein Bild Asset aus einer Datei geöffnet, decodiert und dann der Decoder und das Asset ordnungsgemäß gelöscht werden. Ein Beispiel für das Rendern des decodierten Bildes findest du im Teapot-Beispiel.
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);