Bilddecoder

Die NDK ImageDecoder API bietet eine Standard-API für Android-C-/C++-Apps zur direkten Decodierung von Bildern. App-Entwickler müssen weder die Java APIs (über JNI) noch die Bilddecodierungsbibliotheken von Drittanbietern verwenden. Mit dieser API und den Codierungsfunktionen im Bitmap-Modul wird Folgendes ermöglicht:

  • Systemeigene Apps und Bibliotheken können kleiner sein, da sie keine eigenen Decodierungsbibliotheken mehr verknüpfen müssen.
  • Anwendungen und Bibliotheken profitieren automatisch von Plattformsicherheitsupdates bis hin zu Decodierungsbibliotheken.
  • Apps können Bilder direkt in den von ihnen bereitgestellten Speicher decodieren. Apps können die Bilddaten dann (falls gewünscht) nachbearbeiten und an OpenGL oder ihren Zeichencode weitergeben.

Auf dieser Seite wird beschrieben, wie Sie die API zum Decodieren eines Bildes verwenden.

Verfügbarkeit und Funktionalität

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.h für den Decoder
  • bitmap.h für den Encoder
  • libjnigraphics.so

Die API unterstützt die folgenden Bildformate:

  • JPEG
  • PNG
  • GIF
  • WebP
  • BMP

  • ICO

  • WBMP

  • HEIF

  • Digitale negative Ergebnisse (über das DNG SDK)

Um alle Verwendungen der decodierten Rohbilder abzudecken, stellt diese API keine übergeordneten Objekte wie solche, die auf decodierten Bildern innerhalb des Java-Frameworks aufbauen, zur Verfügung. Beispiele:

  • Drawable-Objekte.
  • NinePatch: Wenn NinePatch-Chunks in einem codierten Image vorhanden sind, werden sie ignoriert.
  • Bitmap-Dichte: AImageDecoder führt keine automatische Größenanpassung basierend auf der Bildschirmdichte aus, ermöglicht jedoch die Decodierung in eine andere Größe über AImageDecoder_setTargetSize().
  • Animationen: Decodiert nur den ersten Frame einer animierten GIF- oder WebP-Datei.

Bilder decodieren

Das Decodieren beginnt mit einer Eingabe, die das codierte Bild darstellt. AImageDecoder akzeptiert mehrere Eingabetypen:

  • AAsset (siehe unten)
  • Dateideskriptor
  • Puffer

Der folgende Code zeigt, wie Sie ein Asset-Bild aus einer Datei öffnen, decodieren und dann den Decoder und das Asset ordnungsgemäß entsorgen. Ein Beispiel für das Rendern des decodierten Bildes finden Sie 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);