أداة فك ترميز الصور

توفّر واجهة برمجة التطبيقات ImageDecoder في حزمة NDK واجهة برمجة تطبيقات عادية لتطبيقات Android المكتوبة بلغة C/C++ لفك ترميز الصور مباشرةً. لم يعد مطوّرو التطبيقات بحاجة إلى استخدام واجهات برمجة تطبيقات Java (من خلال JNI) أو مكتبات فك ترميز الصور التابعة لجهات خارجية. تتيح واجهة برمجة التطبيقات هذه، إلى جانب دوال الترميز في وحدة Bitmap، ما يلي:

  • يمكن أن تكون التطبيقات والمكتبات الأصلية أصغر حجمًا لأنّه لم يعد عليها ربط مكتبات فك التشفير الخاصة بها.
  • تستفيد التطبيقات والمكتبات تلقائيًا من تحديثات أمان النظام الأساسي لمعالجة مكتبات الترميز والتشفير.
  • يمكن للتطبيقات فك ترميز الصور مباشرةً في الذاكرة التي تقدّمها. ويمكن للتطبيقات بعد ذلك إجراء معالجة ما بعد لبيانات الصورة (إذا لزم الأمر) وتمريرها إلى OpenGL أو رمز الرسم الخاص بها.

توضّح هذه الصفحة كيفية استخدام واجهة برمجة التطبيقات لفك ترميز صورة.

مدى التوفّر والإمكانات

تتوفّر واجهة برمجة التطبيقات ImageDecoder في التطبيقات التي تستهدف Android 11 (المستوى 30 لواجهة برمجة التطبيقات) أو الإصدارات الأحدث. تم التنفيذ داخل الملفات التالية:

  • imagedecoder.h لبرنامج فك الترميز
  • bitmap.h لبرنامج الترميز
  • libjnigraphics.so

تتيح واجهة برمجة التطبيقات تنسيقات الصور التالية:

  • JPEG
  • PNG
  • ملف GIF
  • تنسيق WebP
  • BMP

  • ICO

  • WBMP

  • HEIF

  • الصور السلبية الرقمية (من خلال حزمة تطوير البرامج DNG SDK)

لتغطية جميع استخدامات الصور الأولية التي تم فك ترميزها، لا تقدّم واجهة برمجة التطبيقات هذه عناصر ذات مستوى أعلى، مثل تلك التي تم إنشاؤها على الصور التي تم فك ترميزها داخل إطار عمل 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);