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 decoderbitmap.h
untuk encoderlibjnigraphics.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 melaluiAImageDecoder_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);