Decodificatore di immagini

L'API NDK ImageDecoder fornisce un'API standard per le app C/C++ per Android per decodificare direttamente le immagini. Gli sviluppatori di app non devono più utilizzare le API Java (tramite JNI) o librerie di decodifica delle immagini di terze parti. Questa API, insieme alle funzioni di codifica nel modulo Bitmap, consente di:

  • Le app e le librerie native possono essere più piccole perché non devono più collegare le proprie librerie di decodifica.
  • Le app e le librerie usufruiscono automaticamente degli aggiornamenti della sicurezza della piattaforma per le librerie di decodifica.
  • Le app possono decodificare le immagini direttamente nella memoria che forniscono. Le app possono quindi post-elaborare i dati dell'immagine (se necessario) e passarli a OpenGL o al loro codice di disegno.

Questa pagina descrive come utilizzare l'API per decodificare un'immagine.

Disponibilità e funzionalità

L'API ImageDecoder è disponibile nelle app che hanno come target Android 11 (livello API 30) o versioni successive. L'implementazione si trova all'interno dei seguenti file:

  • imagedecoder.h per il decoder
  • bitmap.h per l'encoder
  • libjnigraphics.so

L'API supporta i seguenti formati immagine:

  • JPEG
  • PNG
  • GIF
  • WebP
  • BMP

  • ICO

  • WBMP

  • HEIF

  • Negativi digitali (tramite l'SDK DNG)

Per coprire tutti gli utilizzi delle immagini non elaborate decodificate, questa API non fornisce oggetti di livello superiore come quelli creati a partire da immagini decodificate all'interno del framework Java, ad esempio:

  • Oggetti Drawable.
  • NinePatch: se presenti in un'immagine codificata, i blocchi NinePatch vengono ignorati.
  • Densità bitmap: AImageDecoder non esegue alcuna regolazione automatica delle dimensioni in base alla densità dello schermo, ma consente la decodifica a una dimensione diversa tramite AImageDecoder_setTargetSize().
  • Animazioni: decodifica solo il primo fotogramma di un file GIF animata o WebP.

Decodificare un'immagine

La decodifica inizia con una forma di input che rappresenta l'immagine codificata. AImageDecoder accetta più tipi di input:

  • AAsset (mostrato di seguito)
  • Descrittore del file
  • Buffer

Il seguente codice mostra come aprire un'immagine Asset da un file, decodificarla e quindi eliminare correttamente il decodificatore e l'asset. Per vedere un esempio di rendering dell'immagine decodificata, consulta l'esempio della teiera.

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);