Decoder gambar

ImageDecoder API NDK menyediakan API standar bagi aplikasi C/C++ Android untuk mendekode gambar secara langsung. Developer aplikasi tidak perlu lagi menggunakan API Java (melalui JNI) atau library decoding gambar pihak ketiga. API ini, beserta fungsi encoding dalam modul Bitmap, memungkinkan hal berikut:

  • Aplikasi dan library native dapat berukuran lebih kecil karena tidak lagi harus menautkan library decoding miliknya sendiri.
  • Aplikasi dan library akan otomatis mendapatkan manfaat dari update keamanan platform untuk library decoding.
  • Aplikasi dapat mendekode gambar secara langsung ke memori yang disediakan. Selanjutnya, aplikasi dapat menjalankan pascapemrosesan pada data gambar (jika diinginkan) dan meneruskannya ke OpenGL atau kode gambarnya.

Halaman ini menjelaskan penggunaan API ini untuk mendekode gambar.

Ketersediaan dan kemampuan

ImageDecoder API tersedia di aplikasi yang menargetkan Android 11 (API level 30) atau yang lebih tinggi. Implementasinya dilakukan dalam file berikut:

  • imagedecoder.h untuk decoder
  • bitmap.h untuk encoder
  • libjnigraphics.so

API ini mendukung format gambar berikut:

  • JPEG
  • PNG
  • GIF
  • WebP
  • BMP

  • ICO

  • WBMP

  • HEIF

  • Digital negative (melalui SDK DNG)

Untuk menangani semua penggunaan gambar raw yang didekode, API ini tidak menyediakan objek dengan level yang lebih tinggi, seperti objek yang dibuat dari gambar yang didekode dalam framework Java, di antaranya:

  • Objek Drawable.
  • NinePatch: Jika ada dalam gambar yang dienkode, potongan NinePatch akan diabaikan.
  • Kepadatan bitmap: AImageDecoder tidak melakukan penyesuaian ukuran secara otomatis berdasarkan kepadatan layar, tetapi memungkinkan proses dekode ke ukuran yang berbeda melalui AImageDecoder_setTargetSize().
  • Animasi: Hanya mendekode frame pertama file WebP atau GIF animasi.

Mendekode gambar

Decoding dimulai dengan beberapa bentuk input yang mewakili gambar yang dienkode. AImageDecoder menerima beberapa jenis input:

  • AAsset (ditunjukkan di bawah)
  • Deskriptor file
  • Buffer

Kode berikut menunjukkan cara membuka Asset gambar dari file, mendekodenya, lalu menghapus decoder dan aset dengan benar. Untuk melihat contoh rendering gambar yang sudah didekode, lihat contoh teapot.

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