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

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

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

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

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

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

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

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

  • JPEG
  • PNG
  • ملف GIF
  • WebP
  • BMP

  • ICO

  • WBMP

  • HEIF

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

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