Decodificador de imagem

A API NDK ImageDecoder fornece uma API padrão para apps Android C/C ++ para decodificar imagens diretamente. Os desenvolvedores de aplicativos não precisam mais usar as APIs Java (via JNI) ou bibliotecas de decodificação de imagens de terceiros. Essa API, com as funções de codificação do módulo Bitmap, permite o seguinte:

  • Os aplicativos e bibliotecas nativos podem ser menores porque não precisam mais vincular as próprias bibliotecas de decodificação.
  • Aplicativos e bibliotecas são automaticamente beneficiados pelas atualizações de segurança da plataforma para bibliotecas de decodificação.
  • Os aplicativos podem decodificar imagens diretamente na memória que fornecem. Em seguida, os apps podem pós-processar os dados da imagem e enviá-los para o OpenGL ou para o código de desenho.

Esta página descreve como usar a API para decodificar uma imagem.

Disponibilidade e capacidade

A API ImageDecoder está disponível em apps direcionados ao Android 11 (API de nível 30) ou versões mais recentes. A implementação está dentro dos seguintes arquivos:

  • imagedecoder.h para o decodificador
  • bitmap.h para o codificador
  • libjnigraphics.so

A API é compatível com os seguintes formatos de imagem:

  • JPEG
  • PNG
  • GIF
  • WebP
  • BMP

  • ICO

  • WBMP

  • HEIF

  • Negativos digitais (por meio do SDK do DNG)

Para abranger todos os usos das imagens brutas decodificadas, essa API não fornece objetos de nível superior, por exemplo, aqueles criados sobre imagens decodificadas dentro do framework Java, como:

  • objetos Drawable;
  • NinePatch: se presente em uma imagem codificada, os blocos NinePatch serão ignorados;
  • densidade de bitmap: AImageDecoder não faz nenhuma modificação automática de tamanho com base na densidade da tela, mas permite a decodificação para um tamanho diferente por AImageDecoder_setTargetSize();
  • Animações: decodifica apenas o primeiro frame de um arquivo GIF ou WebP animado.

Decodificar uma imagem

A decodificação começa com alguma forma de entrada que representa a imagem codificada. AImageDecoder aceita vários tipos de entrada:

  • AAsset (mostrado abaixo)
  • Descritor do arquivo
  • Buffer

O código a seguir mostra como abrir uma imagem Asset de um arquivo, decodificá-la e descartar corretamente o decodificador e o recurso. Para ver um exemplo de renderização da imagem decodificada, consulte a amostra Teapot (link em inglês).

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