Отображение анимированных GIF в Android: преобразование в Drawable

Пройдите тест, узнайте какой профессии подходите

Я предпочитаю
0%
Работать самостоятельно и не зависеть от других
Работать в команде и рассчитывать на помощь коллег
Организовывать и контролировать процесс работы

Быстрый ответ

Чтобы вывести анимированные GIF в Java, можно воспользоваться классами ImageIcon и JLabel:

Java
Скопировать код
import javax.swing.*;

public class GifDisplay {
    public static void main(String[] args) {
        ImageIcon gif = new ImageIcon("animated.gif"); // замените на путь к вашему GIF-файлу
        JLabel label = new JLabel(gif);

        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(label);
        frame.pack();
        frame.setVisible(true); // выполняем анимацию!
    }
}

Просто замените "animated.gif" на путь к вашему GIF-файлу, и анимация на экране начнется.

Кинга Идем в IT: пошаговый план для смены профессии

Альтернативные методы для разных сред разработки

Если работаете не c Swing и GIF-анимация у вас не работает, вы можете воспользоваться различными методами, подходящими для вашей среды разработки, включая Android.

Использование Glide в Android

Для разработчиков под Android библиотека Glide значительно упрощает работу с анимированными GIF:

Java
Скопировать код
Glide.with(context).asGif().load(GIF_URI).into(imageView); // загружаем и выводим анимацию!

Использование WebView для вывода анимированных GIF

Не все помнят, что можно использовать WebView для вывода анимированных GIF с использованием HTML. Примените метод loadDataWithBaseURL() для загрузки анимации:

Java
Скопировать код
String html = "<html><body style='margin:0;padding:0;'><img src='file:///android_asset/animated.gif' /></body></html>";
webView.loadDataWithBaseURL(null, html, "text/html", "UTF-8", null); // профессиональное встраивание GIF!

Использование AnimationDrawable для управления анимацией по кадрам

Если вы хотите управлять анимацией GIF по кадрам, используйте AnimationDrawable. Это позволит преобразовать GIF в серию объектов Drawable для детальной настройки анимации:

Java
Скопировать код
AnimationDrawable animation = new AnimationDrawable();
animation.addFrame(getResources().getDrawable(R.drawable.frame1), 100);
animation.addFrame(getResources().getDrawable(R.drawable.frame2), 100);
//... создаём анимацию
imageView.setBackground(animation);
animation.start();

Визуализация

Чтобы лучше понять механизм отображения анимированного GIF, давайте проведем аналогию с поездом, движущимся по железной дороге:

Markdown
Скопировать код
// Тут ваше Java-приложение
// А здесь анимированный GIF

Представим класс JLabel как платформу, на которую прибывает этот поезд:

Java
Скопировать код
JLabel label = new JLabel(new ImageIcon("train.gif")); // принимаем GIF-поезд!

Пользователи (пассажиры) наблюдают гладко движущийся GIF (проходящий поезд):

Markdown
Скопировать код
Пользовательский интерфейс: 🚉👀🚂💨

Если код (рельсы) написан без ошибок, анимированный GIF (поезд) будет двигаться по метке (JLabel) без препятствий.

Продвинутые техники работы с GIF

Рассмотрим более сложные сценарии и реализации анимированных GIF.

Оптимизация больших GIF

При работе с большими GIF акцент делается на производительности их загрузки. Чтобы оптимизировать процесс, нужно разбивать GIF на кадры и контролировать использование памяти:

Java
Скопировать код
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(new File(GIF_PATH))); // каждый пиксель имеет значение 😉
Movie movie = Movie.decodeStream(bis);

Настраиваемая отрисовка

Создание класса, наследующего View, позволяет получить широкие возможности для точного и эффективного вывода анимированных GIF:

Java
Скопировать код
public class CustomGifView extends View {
    private Movie movie; // наш фильм!
    public CustomGifView(Context context, AttributeSet attrs) {
        super(context, attrs);
        InputStream is = context.getResources().openRawResource(R.raw.animated_gif);
        movie = Movie.decodeStream(is); // поднимаем занавес!
    }
    @Override
    protected void onDraw(Canvas canvas) {
        long now = SystemClock.uptimeMillis(); // время течет!
        if (movie != null) {
            int dur = movie.duration();
            if (dur == 0) {
                dur = 1000; // быстро как мгновение!
            }
            int relTime = (int)((now % dur));
            movie.setTime(relTime);
            movie.draw(canvas, 0, 0);
            invalidate(); // не забудьте обновлять холст!
        }
    }
}

Работа со сложными анимациями в Glide

Библиотека Glide упрощает работу не только с простыми изображениями. Особенно эффективным она оказывается при работе с анимированными GIF, так как берет на себя обязанности по декодированию, кешированию и управлению памятью:

Java
Скопировать код
Glide.with(this).load(gifUrl).into(new DrawableImageViewTarget(imageView)); // выполняем всю тяжелую работу за вас!

Полезные материалы

  1. Использование иконок (руководство по Swing)
  2. ImageView (JavaFX 8)
  3. Как добавить изображение в JPanel (Stack Overflow)
  4. Graphics2D (Java Platform SE 7)
  5. Обучение 2D-графике (руководство по Java)
  6. Чтение и загрузка изображений (руководство по Swing)
  7. BufferedInputStream (Java Platform SE 8)