2015-08-27 3 views
0

Я пытаюсь извлечь все рамки анимированного gif в массив bufferedimages. Я читал Convert each animated GIF frame to a separate BufferedImage, и было довольно легко записать каждый кадр в отдельный файл. Но моя проблема возникает, когда я пытаюсь заполнить ArrayList кадрами, а не писать их. Каждое изображение в ArrayList - это только последний кадр gif.Анимированные рамки Gif к массиву BufferedImages

Чтобы сделать его более понятным, этот код будет записывать каждый кадр, чтобы отделить файлы отлично:

ArrayList<BufferedImage> frames = new ArrayList<BufferedImage>(); 
    BufferedImage master = new BufferedImage(128, 128, BufferedImage.TYPE_INT_ARGB); 

    ImageReader ir = new GIFImageReader(new GIFImageReaderSpi()); 
    ir.setInput(ImageIO.createImageInputStream(gif)); 
    for (int i = 0; i < ir.getNumImages(true); i++) 
    { 
     master.getGraphics().drawImage(ir.read(i), 0, 0, null); 
     ImageIO.write(master, "gif", new File(dirGifs + "/frames" + i + ".gif")); 
    } 

Однако, этот код будет только дает мне ArrayList полный одного и того же кадра (будучи последний кадр из GIF)

ArrayList<BufferedImage> frames = new ArrayList<BufferedImage>(); 
    BufferedImage master = new BufferedImage(128, 128, BufferedImage.TYPE_INT_ARGB); 

    ImageReader ir = new GIFImageReader(new GIFImageReaderSpi()); 
    ir.setInput(ImageIO.createImageInputStream(gif)); 
    for (int i = 0; i < ir.getNumImages(true); i++) 
    { 
     master.getGraphics().drawImage(ir.read(i), 0, 0, null); 
     frames.add(master); 
    } 

Я думал, что это было, потому что я не был расправившись с графикой впоследствии, но я попытался создать графический объект и размещения его и ничего не изменилось. Нужна помощь!

ответ

2

Это потому, что BufferedImage master хранится в ArrayList как ссылка, а не как копия. Поэтому каждый элемент ArrayList указывает на тот же BufferedImage. Я думаю, что самый простой способ решить это - просто положить строку BufferedImage master = new BufferedImage(128, 128, BufferedImage.TYPE_INT_ARGB); внутри цикла for, поэтому на каждой итерации создается новый экземпляр BufferedImage.

+0

Мне нужно нарисовать поверх главного изображения каждую итерацию, чтобы новый экземпляр не работал. Так что я сделал, это создать новый экземпляр для каждого элемента массива, а затем установить его данные в соответствие с основным изображением. Спасибо, ваш ответ помог мне найти решение очень быстро – Sixtoo

0

Colouredmirrorball указал, что я могу решить эту проблему, создав новый экземпляр bufferedimage. Поэтому я сначала создал новый экземпляр для каждого элемента массива, а затем установил данные элемента так же, как и основное изображение. Следующий фрагмент кода дает мне массив кадров, извлеченных из анимированного gif-файла.

public ArrayList<BufferedImage> getFrames(File gif) throws IOException { 
    ArrayList<BufferedImage> frames = new ArrayList<BufferedImage>(); 
    BufferedImage master = new BufferedImage(128, 128, BufferedImage.TYPE_INT_ARGB); 

    ImageReader ir = new GIFImageReader(new GIFImageReaderSpi()); 
    ir.setInput(ImageIO.createImageInputStream(gif)); 
    for (int i = 0; i < ir.getNumImages(true); i++) { 
     frames.add(new BufferedImage(128, 128, BufferedImage.TYPE_INT_ARGB)); 
     master.getGraphics().drawImage(ir.read(i), 0, 0, null); 
     frames.get(i).setData(master.getData()); 
    } 
    return frames; 
}