Resim kod çözücüsü

NDK ImageDecoder API, Android C/C++ uygulamalarının görüntülerin kodunu doğrudan çözmesi için standart bir API sağlar. Uygulama geliştiricilerin artık Java API'lerini (JNI aracılığıyla) veya üçüncü taraf görüntü kod çözme kitaplıklarını kullanmalarına gerek yoktur. Bu API, Bitmap modülündeki kodlama işlevleriyle birlikte aşağıdakileri sağlar:

  • Artık kendi kod çözme kitaplıklarını bağlamaları gerekmediği için yerel uygulamalar ve kitaplıklar daha küçük olabilir.
  • Uygulamalar ve kitaplıklar, kitaplıkların kodunu çözmeye yönelik platform güvenliği güncellemelerinden otomatik olarak yararlanır.
  • Uygulamalar, resimlerin kodunu doğrudan kendi sağladıkları bellekte çözebilir. Uygulamalar daha sonra görüntü verilerini (istenirse) tekrar işleyebilir ve OpenGL'ye veya kendi çizim kodlarına iletebilir.

Bu sayfada, bir resmin kodunu çözmek için API'nin nasıl kullanılacağı açıklanmaktadır.

Kullanılabilirlik ve özellik

ImageDecoder API'si, Android 11 (API düzeyi 30) veya sonraki sürümleri hedefleyen uygulamalarda kullanılabilir. Uygulama aşağıdaki dosyaların içindedir:

  • Kod çözücü için imagedecoder.h
  • Kodlayıcı için bitmap.h
  • libjnigraphics.so

API aşağıdaki resim biçimlerini destekler:

  • JPEG
  • PNG
  • GIF
  • WebP
  • BMP

  • ICO

  • WBMP

  • HEIF

  • Dijital negatifler (DNG SDK'sı aracılığıyla)

Bu API, kodu çözülmüş ham görüntülerin tüm kullanımlarını kapsamak için, Java çerçevesi içindeki kodu çözülmüş görüntülerin üzerinde oluşturulanlar gibi daha yüksek seviyeli nesneler sağlamaz. Örneğin:

  • Drawable nesne.
  • NinePatch: Kodlanmış bir resimde varsa NinePatch parçaları yoksayılır.
  • Bit eşlem yoğunluğu: AImageDecoder, ekranın yoğunluğuna göre otomatik boyut ayarlaması yapmaz ancak AImageDecoder_setTargetSize() üzerinden farklı bir boyutun şifresinin çözülmesine olanak tanır.
  • Animasyonlar: Yalnızca animasyonlu bir GIF veya WebP dosyasının ilk karesinin kodunu çözer.

Bir resmin kodunu çözme

Kod çözme işlemi, kodlanmış görüntüyü temsil eden bir giriş biçimiyle başlar. AImageDecoder birden fazla giriş türünü kabul eder:

  • AAsset (aşağıda gösterilmiştir)
  • Dosya açıklayıcı
  • Tampon

Aşağıdaki kodda, bir dosyadan Asset resminin nasıl açılacağı, kodun nasıl çözüleceği ve ardından kod çözücü ile öğenin nasıl uygun şekilde kaldırılacağı gösterilmektedir. Kodu çözülmüş resmin oluşturulmasına dair bir örnek görmek için çaydanlık örneğine bakın.

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);