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

توفّر واجهة برمجة تطبيقات NDK ImageDecoder واجهة برمجة تطبيقات قياسية لتطبيقات 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);