NDK ImageDecoder
API 提供標準 API,可讓 Android C/C++ 應用程式直接將圖片解碼。應用程式開發人員不再需要使用 Java API (透過 JNI) 或第三方圖片解碼程式庫。這個 API 與 Bitmap 模組中的編碼函式搭配使用時,能夠達成以下效益:
- 縮小原生應用程式和程式庫的大小,因為不再需要連結自己的解碼程式庫。
- 應用程式和程式庫會自動受益於解碼程式庫的平台安全性更新。
- 應用程式可以直接將圖片解碼至本身提供的記憶體。然後,應用程式可視需要對圖片資料進行後續處理,並將資料傳送至 OpenGL 或其繪圖程式碼。
本頁面說明如何使用 API 將圖片解碼。
適用情形和功能
ImageDecoder
API 適用於目標為 Android 11 (API 級別 30) 以上版本的應用程式,並在下列檔案中實作:
imagedecoder.h
,適用於解碼器bitmap.h
,適用於編碼器libjnigraphics.so
API 支援下列圖片格式:
- JPEG
- PNG
- GIF
- WebP
BMP
ICO
WBMP
HEIF
數位負片 (透過 DNG SDK)
為涵蓋已解碼原始圖片的所有使用情況,這個 API 不提供更高層級的物件 (比如在 Java 架構中以已解碼圖片建構的物件),例如:
Drawable
物件。NinePatch
:如果出現在編碼圖片中,系統會忽略 NinePatch 區塊。- 點陣圖密度:
AImageDecoder
不會根據螢幕密度自動調整大小,但允許透過AImageDecoder_setTargetSize()
將其解碼為不同大小。 - 動畫:只會將 GIF 動畫或 WebP 檔案的第一個影格解碼。
將圖片解碼
解碼作業會從代表已編碼圖片的某種輸入形式開始進行。
AImageDecoder
接受多種輸入類型:
AAsset
(如下所示)- 檔案描述元
- 緩衝區
下列程式碼顯示如何從檔案開啟圖片 Asset
並進行解碼,然後正確處理解碼器和素材資源。如要查看算繪已解碼圖片的範例,請參閱茶壺範例。
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);