رمزگشای تصویر

NDK ImageDecoder API یک API استاندارد برای برنامه‌های Android C/C++ برای رمزگشایی مستقیم تصاویر ارائه می‌کند. توسعه دهندگان برنامه دیگر نیازی به استفاده از API های جاوا (از طریق JNI) یا کتابخانه های رمزگشایی تصویر شخص ثالث ندارند. این API، همراه با توابع رمزگذاری در ماژول Bitmap ، موارد زیر را فعال می کند:

  • برنامه‌ها و کتابخانه‌های بومی می‌توانند کوچک‌تر باشند، زیرا دیگر مجبور نیستند کتابخانه‌های رمزگشایی خود را پیوند دهند.
  • برنامه‌ها و کتابخانه‌ها به‌طور خودکار از به‌روزرسانی‌های امنیتی پلتفرم برای رمزگشایی کتابخانه‌ها بهره می‌برند.
  • برنامه ها می توانند تصاویر را مستقیماً در حافظه ای که ارائه می کنند رمزگشایی کنند. سپس برنامه ها می توانند داده های تصویر را پس از پردازش (در صورت تمایل) و ارسال آن به OpenGL یا کد طراحی خود.

در این صفحه نحوه استفاده از API برای رمزگشایی یک تصویر توضیح داده شده است.

در دسترس بودن و قابلیت

ImageDecoder API در برنامه هایی موجود است که اندروید 11 (سطح API 30) یا بالاتر را هدف قرار می دهند. پیاده سازی داخل فایل های زیر است:

  • imagedecoder.h برای رمزگشا
  • bitmap.h برای رمزگذار
  • libjnigraphics.so

API از فرمت های تصویر زیر پشتیبانی می کند:

  • JPEG
  • PNG
  • GIF
  • وب پی
  • BMP

  • ICO

  • WBMP

  • HEIF

  • نگاتیوهای دیجیتال (از طریق DNG SDK)

به منظور پوشش همه موارد استفاده از تصاویر خام رمزگشایی شده، این API اشیاء سطح بالاتری مانند موارد ساخته شده در بالای تصاویر رمزگشایی شده در چارچوب جاوا را ارائه نمی دهد، مانند:

  • اشیاء 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);