Фон
Я пытаюсь просмотреть растровые изображения анимированных файлов GIF и WEBP вручную (кадр за кадром), чтобы это работало не только для видов, но и для других случаев (например, для живых обоев).
Эта проблема
Анимированные файлы GIF/WEBP поддерживаются только из Android P с использованием ImageDecoder API (пример здесь).
Для GIF я хотел попробовать Glide для этой задачи, но у меня не получилось, поэтому я попытался преодолеть это, используя библиотеку, которая позволяет загружать их ( здесь, решение здесь). Я думаю, что это работает отлично.
Для WebP, я думал, что я нашел другую библиотеку, которая могла бы работать на старые версии Android ( здесь, сделал вилку здесь), но мне кажется, что он не может обрабатывать файлы WebP а в некоторых случаях (сообщенные здесь). Я пытался выяснить, в чем проблема и как ее решить, но мне это не удалось.
Итак, предполагая, что когда-нибудь Google будет поддерживать анимацию GIF & WEBP для более старых версий Android через библиотеку поддержки (они написали это здесь), я решил попытаться использовать ImageDecoder для этой задачи.
Дело в том, что, глядя на весь API ImageDecoder, он довольно ограничен в том, как мы должны его использовать. Я не понимаю, как я могу преодолеть его ограничения.
Что я нашел
Вот как ImageDecoder может использоваться для отображения анимированной WebP на ImageView (просто образец, конечно, доступен здесь):
class MainActivity : AppCompatActivity() {
@SuppressLint("StaticFieldLeak")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val source = ImageDecoder.createSource(resources, R.raw.test)
object : AsyncTask<Void, Void, Drawable?>() {
override fun doInBackground(vararg params: Void?): Drawable? {
return try {
ImageDecoder.decodeDrawable(source)
} catch (e: Exception) {
null
}
}
override fun onPostExecute(result: Drawable?) {
super.onPostExecute(result)
imageView.setImageDrawable(result)
if (result is AnimatedImageDrawable) {
result.start()
}
}
}.execute()
}
}
Я попытался прочитать все документы ImageDecoder и AnimatedImageDrawable, а также взглянуть на их код, но я не понимаю, как можно вручную пройтись по каждому кадру, и есть время, которое нужно ждать между ними.
Вопросы
-
Есть ли способ использовать ImageDecoder API для обхода каждого кадра вручную, чтобы получить растровое изображение для рисования и узнать, сколько нужно времени для ожидания между кадрами? Есть ли обходной путь? Может быть, даже используя AnimatedImageDrawable?
-
Я хотел бы сделать то же самое на старых версиях Android. Является ли это возможным? Если так, как? Может быть, на другом API/библиотеке? Google написал, что он работает над способом использования ImageDecoder в более старых версиях Android, но я не вижу, чтобы он упоминался нигде (за исключением ссылки, которую я предоставил). Вероятно, еще не готов... Android P еще не достиг 0,1% пользователей... Может быть, Fresco может это сделать? Я тоже пытался это проверить, но не вижу, что он способен на такую вещь, и это огромная библиотека, которую можно использовать только для этой задачи, поэтому я бы предпочел использовать другую библиотеку вместо этого... Я также знаю, что libwebp доступен, но он в C/C++ и не уверен, подходит ли он для Android, и есть ли для него порт на Java/Kotlin для Android.
РЕДАКТИРОВАТЬ:
Поскольку я думаю, что получил то, что хотел, как для сторонней библиотеки, так и для ImageDecoder, чтобы иметь возможность получать растровые изображения из анимированного WebP, я все же хотел бы знать, как получить количество кадров и текущий кадр с помощью ImageDecoder, если это возможно Я попытался использовать ImageDecoder.decodeDrawable(source, object: ImageDecoder.OnHeaderDecodedListener...
, но он не предоставляет информацию о количестве кадров, и в API нет способа увидеть, что я могу перейти к определенному индексу кадра и начать с этого или узнать для конкретного кадра, как долго нужно переходить к следующему кадру, поэтому я сделал запрос о них здесь.
К сожалению, я также не мог найти, что Google имеет ImageDecoder, доступный для более старых версий Android, также.
Также интересно, если есть какой-то способ сделать то же самое, что я сделал для относительно нового файла анимации HEIC. В настоящее время поддерживается только на Android P.