מפענח תמונות

ממשק ה-API ImageDecoder של NDK מספק ממשק 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 הזה לא מספק אובייקטים ברמה גבוהה יותר, כמו אובייקטים שנוצרו מעל תמונות שעבר תהליך פענוח בתוך מסגרת Java, למשל:

פענוח תמונה

תהליך הפענוח מתחיל עם סוג כלשהו של קלט שמייצג את התמונה המקודדת. 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);