Java GIF анимация не перерисовывается правильно

Я пытаюсь оживить изображение GIF. Анимация работает, но она плохо рисуется.

Он показывает это (не анимированный снимок экрана): Как я это вижу

На изображении хвост валяется так: Это был образ, который я использовал

Как вы можете видеть, изображение не перекрашивается хорошо. Я не хочу использовать JLabels, но это не сработало правильно, поэтому я последовал этому вопросу, когда мой образ не оживился .

Мой код выглядит так:

public void draw(JPanel canvas, Graphics2D g2d, int x, int y) { getFrontImage().paintIcon(canvas, g2d, x, y); } 

Где изображение извлекается и сохраняется следующим образом:

 ImageIcon gif = new ImageIcon(getClass().getResource(filename)); 

В canvasе JPanel я сделал метод рисования и stream таймера, который реплицирует каждые 10 мс. Это работает для всего, кроме GIF. Кто бы мог мне помочь?

— Редактировать

Прошу прощения за недоразумение, я обновил изображение до того, что я использую. Надеюсь, это не слишком много хлопот, чтобы получить ответ правильно …

Хорошо, поэтому, после долгих размахов, я смог, наконец, изменить способ удаления frameworks для restoreToBackgroundColor . В основном, это означает, что анимация не является инкрементным изменением, а полной заменой кадра …

цицероGif

 import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.EventQueue; import java.awt.Graphics; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.ImageIcon; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.Timer; import javax.swing.UIManager; import javax.swing.UnsupportedLookAndFeelException; public class AnimatedGifTest1 { public static void main(String[] args) { new AnimatedGifTest1(); } public AnimatedGifTest1() { EventQueue.invokeLater(new Runnable() { @Override public void run() { try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } catch (ClassNotFoundException ex) { } catch (InstantiationException ex) { } catch (IllegalAccessException ex) { } catch (UnsupportedLookAndFeelException ex) { } JFrame frame = new JFrame("Test"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setLayout(new BorderLayout()); frame.add(new PaintPane()); frame.pack(); frame.setLocationRelativeTo(null); frame.setVisible(true); } }); } public class PaintPane extends JPanel { private ImageIcon image; public PaintPane() { image = new ImageIcon(getClass().getResource("/ertcM02.gif")); Timer timer = new Timer(40, new ActionListener() { @Override public void actionPerformed(ActionEvent e) { repaint(); } }); timer.start(); } @Override public Dimension getPreferredSize() { return image == null ? new Dimension(200, 200) : new Dimension(image.getIconWidth(), image.getIconHeight()); } @Override protected void paintComponent(Graphics g) { super.paintComponent(g); // This is very important! int x = (getWidth() - image.getIconWidth()) / 2; int y = (getHeight() - image.getIconHeight()) / 2; image.paintIcon(this, g, x, y); } } } 

Обновление …

Таким образом, я наконец-то смог взглянуть на метод удаления для используемого gif, который настроен на restoreToPrevious , который, согласно GRAPHICS INTERCHANGE FORMAT Version 89a, означает:

Восстановить до предыдущего. Декодер требуется для восстановления области, перезаписанной графикой, с тем, что было до рендеринга графики.

Где в качестве изображения, которое я предоставил выше, используется restoreToBackgroundColor , который в соответствии с GRAPHICS INTERCHANGE FORMAT Version 89a означает:

Восстановить цвет фона. Область, используемая графикой, должна быть восстановлена ​​до цвета фона

Вы можете проверить это самостоятельно, используя следующий код …

 public static class AnimatedGif { public enum DisposalMethod { RESTORE_TO_BACKGROUND, RESTORE_TO_PREVIOUS, DO_NOT_DISPOSE, UNSPECIFIED; public static DisposalMethod find(String text) { DisposalMethod dm = UNSPECIFIED; System.out.println(text); switch (text) { case "restoreToBackgroundColor": dm = RESTORE_TO_BACKGROUND; break; case "restoreToPrevious": dm = RESTORE_TO_PREVIOUS; break; } return dm; } } private List frames; private int frame; public AnimatedGif(JComponent player, URL url) throws IOException { frames = new ArrayList<>(25); try (InputStream is = url.openStream(); ImageInputStream stream = ImageIO.createImageInputStream(is)) { Iterator readers = ImageIO.getImageReaders(stream); if (!readers.hasNext()) { throw new RuntimeException("no image reader found"); } ImageReader reader = (ImageReader) readers.next(); reader.setInput(stream); // don't omit this line! int n = reader.getNumImages(true); // don't use false! System.out.println("numImages = " + n); for (int i = 0; i < n; i++) { BufferedImage image = reader.read(i); ImageFrame imageFrame = new ImageFrame(image); IIOMetadata imd = reader.getImageMetadata(i); Node tree = imd.getAsTree("javax_imageio_gif_image_1.0"); NodeList children = tree.getChildNodes(); for (int j = 0; j < children.getLength(); j++) { Node nodeItem = children.item(j); NamedNodeMap attr = nodeItem.getAttributes(); switch (nodeItem.getNodeName()) { case "ImageDescriptor": ImageDescriptor id = new ImageDescriptor( getIntValue(attr.getNamedItem("imageLeftPosition")), getIntValue(attr.getNamedItem("imageTopPosition")), getIntValue(attr.getNamedItem("imageWidth")), getIntValue(attr.getNamedItem("imageHeight")), getBooleanValue(attr.getNamedItem("interlaceFlag"))); imageFrame.setImageDescriptor(id); break; case "GraphicControlExtension": GraphicControlExtension gc = new GraphicControlExtension( DisposalMethod.find(getNodeValue(attr.getNamedItem("disposalMethod"))), getBooleanValue(attr.getNamedItem("userInputFlag")), getBooleanValue(attr.getNamedItem("transparentColorFlag")), getIntValue(attr.getNamedItem("delayTime")) * 10, getIntValue(attr.getNamedItem("transparentColorIndex"))); imageFrame.setGraphicControlExtension(gc); break; } } frames.add(imageFrame); } } finally { } } protected String getNodeValue(Node node) { return node == null ? null : node.getNodeValue(); } protected int getIntValue(Node node) { return node == null ? 0 : getIntValue(node.getNodeValue()); } protected boolean getBooleanValue(Node node) { return node == null ? false : getBooleanValue(node.getNodeValue()); } protected int getIntValue(String value) { return value == null ? 0 : Integer.parseInt(value); } protected boolean getBooleanValue(String value) { return value == null ? false : Boolean.parseBoolean(value); } public class ImageFrame { private BufferedImage image; private ImageDescriptor imageDescriptor; private GraphicControlExtension graphicControlExtension; public ImageFrame(BufferedImage image) { this.image = image; } protected void setImageDescriptor(ImageDescriptor imageDescriptor) { this.imageDescriptor = imageDescriptor; } protected void setGraphicControlExtension(GraphicControlExtension graphicControlExtension) { this.graphicControlExtension = graphicControlExtension; System.out.println(graphicControlExtension.getDisposalMethod()); } public GraphicControlExtension getGraphicControlExtension() { return graphicControlExtension; } public BufferedImage getImage() { return image; } public ImageDescriptor getImageDescriptor() { return imageDescriptor; } } public class GraphicControlExtension { private DisposalMethod disposalMethod; private boolean userInputFlag; private boolean transparentColorFlag; private int delayTime; private int transparentColorIndex; public GraphicControlExtension(DisposalMethod disposalMethod, boolean userInputFlag, boolean transparentColorFlag, int delayTime, int transparentColorIndex) { this.disposalMethod = disposalMethod; this.userInputFlag = userInputFlag; this.transparentColorFlag = transparentColorFlag; this.delayTime = delayTime; this.transparentColorIndex = transparentColorIndex; } public int getDelayTime() { return delayTime; } public DisposalMethod getDisposalMethod() { return disposalMethod; } public int getTransparentColorIndex() { return transparentColorIndex; } public boolean isTransparentColorFlag() { return transparentColorFlag; } public boolean isUserInputFlag() { return userInputFlag; } } public class ImageDescriptor { private int imageLeftPosition; private int imageTopPosition; private int imageHeight; private int imageWeight; private boolean interlaced; public ImageDescriptor(int imageLeftPosition, int imageTopPosition, int imageHeight, int imageWeight, boolean interlaced) { this.imageLeftPosition = imageLeftPosition; this.imageTopPosition = imageTopPosition; this.imageHeight = imageHeight; this.imageWeight = imageWeight; this.interlaced = interlaced; } public int getImageHeight() { return imageHeight; } public int getImageLeftPosition() { return imageLeftPosition; } public int getImageTopPosition() { return imageTopPosition; } public int getImageWeight() { return imageWeight; } public boolean isInterlaced() { return interlaced; } } } 

Этот код исходит из .gif. Изображение не перемещается при добавлении его в панель JTabbed.

  • Нарисуйте строку в JPanel с нажатием кнопки на Java
  • Проблема с перерисованием JPanel
  • Как изменить стиль стрелки в JComboBox
  • Автоматическая настройка высоты строк в JTable
  • Как обеспечить поддержку разбивки на страницы JTable в Swing?
  • Как рендерить часть в Swing JComponents
  • расширенное форматирование ввода текста в текстовом поле?
  • переместить компонент после перетаскивания
  • Добавить эскизы изображений к макету в сетке?
  • Заполнение combobox из базы данных с помощью hibernate в Java
  • Порядок срабатывания EventListenerList
  • Давайте будем гением компьютера.