Справочник API: Codec (Декодирование и анимация)
Хотя Image.makeDeferredFromEncodedBytes() подходит для простых статичных изображений, класс Codec необходим, когда требуется больше контроля над процессом декодирования или при работе с анимированными изображениями (GIF, анимированный WebP).
Загрузка Codec
Codec представляет собой "источник" изображения до его преобразования в пиксели.
java
Data data = Data.makeFromFileName("animations/loading.gif");
Codec codec = Codec.makeFromData(data);Базовое декодирование
Чтобы получить один статичный кадр из кодека:
java
Bitmap bmp = new Bitmap();
bmp.allocPixels(codec.getImageInfo()); // Подготовить память
codec.readPixels(bmp); // Декодировать данные в битмапРабота с анимацией
Здесь Codec раскрывает свои возможности. Он позволяет перебирать кадры GIF или WebP.
java
int frameCount = codec.getFrameCount();
int loopCount = codec.getRepetitionCount(); // -1 для бесконечного цикла
for (int i = 0; i < frameCount; i++) {
// 1. Получить информацию о конкретном кадре (длительность и т.д.)
AnimationFrameInfo info = codec.getFrameInfo(i);
int duration = info.getDuration(); // в миллисекундах
// 2. Декодировать кадр
Bitmap frameBmp = new Bitmap();
frameBmp.allocPixels(codec.getImageInfo());
codec.readPixels(frameBmp, i);
// 3. Сделать что-то с кадром...
}Расширенные параметры декодирования
Масштабирование во время декодирования
Если у вас есть изображение 4K, но нужно только 200x200, можно указать кодеку масштабировать его во время процесса декодирования. Это намного быстрее и требует значительно меньше памяти, чем декодирование полного изображения с последующим масштабированием.
java
ImageInfo smallInfo = ImageInfo.makeN32Premul(200, 200);
Bitmap smallBmp = new Bitmap();
smallBmp.allocPixels(smallInfo);
codec.readPixels(smallBmp); // Декодирует и масштабирует за один шаг!Важные примечания
- Перемотка потока: Некоторые кодеки (в зависимости от исходных данных) нельзя перематывать. Если нужно декодировать кадры несколько раз, безопаснее хранить
Dataв памяти. - Цветовые пространства: Кодек попытается учесть цветовое пространство, встроенное в изображение. Это можно переопределить, передав другой
ImageInfoвreadPixels. - Память: Сам
Codecзанимает мало места, но объектыBitmap, в которые происходит декодирование, могут быть очень большими. По возможности переиспользуйте битмапы.