API של NDK ImageDecoder
מספק
API סטנדרטי לאפליקציות Android C/C++ כדי לפענח תמונות באופן ישיר. מספר מפתחי אפליקציות
צורך יותר זמן ב-API של Java (דרך JNI) או בפענוח תמונה של צד שלישי
של הספריות. ה-API הזה, יחד עם פונקציות הקידוד
המודול Bitmap מאפשר את הפעולות הבאות:
- ספריות ואפליקציות מקוריות יכולות להיות קטנות יותר, כי הן כבר לא צריכות לקשר ספריות פענוח משלהם.
- אפליקציות וספריות נהנות באופן אוטומטי מעדכוני אבטחת פלטפורמה של ספריות לפענח ספריות.
- אפליקציות יכולות לפענח תמונות ישירות לזיכרון שהן מספקות. לאחר מכן האפליקציות יכולות אחרי העיבוד של נתוני התמונה (אם רוצים) ולהעביר אותם ל-OpenGL או באמצעות קוד שרטוט.
בדף הזה נסביר איך להשתמש ב-API כדי לפענח תמונה.
זמינות ויכולת
ה-API של ImageDecoder
זמין באפליקציות שמטרגטות את Android 11 (רמת API 30)
ומעלה. ההטמעה נמצאת בתוך הקבצים הבאים:
imagedecoder.h
למפענחbitmap.h
למקודדlibjnigraphics.so
ה-API תומך בפורמטים הבאים של תמונות:
- JPEG
- PNG
- GIF
- WebP
BMP
ICO
WBMP
HEIF
דיגיטליים שליליים (דרך DNG SDK)
כדי לכסות את כל השימושים בתמונות גולמיות מפוענחות, ה-API הזה לא לספק אובייקטים ברמה גבוהה יותר, כמו אובייקטים שבנויים על תמונות מפוענחות שבפנים. למשל:
Drawable
אובייקטים.NinePatch
: אם נמצא תמונה מקודדת, המערכת מתעלמת ממקטעי NinePatch.- צפיפות מפת סיביות (Bitmap):
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);