изменение размера анимированного GIF с сохранением анимации с использованием Java - PullRequest
7 голосов
/ 22 февраля 2012

Я использую Graphics2D в java для изменения размера изображений, он прекрасно работает с jpg, png и другими форматами. Моя проблема - анимированные GIF-изображения, после изменения размера анимация исчезла!

вот метод, который я использую:

    private BufferedImage doResize(int newWidth, int newHeight, double scaleX,
        double scaleY, BufferedImage source) {

    GraphicsConfiguration gc = getDefaultConfiguration();
    BufferedImage result = gc.createCompatibleImage(newWidth, newHeight, source.getColorModel().getTransparency());
    Graphics2D g2d = null;

    try {
        g2d = result.createGraphics();
        g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
        g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
        g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2d.scale(scaleX, scaleY);
        g2d.drawImage(source, 0, 0, null);
    } finally {
        if (g2d != null) {
            g2d.dispose();
        }
    }

    return result;
}

Итак, какие-нибудь подсказки, как я могу сохранить анимированный GIF после изменения размера? Спасибо.

Ответы [ 2 ]

6 голосов
/ 03 июля 2013

Я нашел два источника, которые при объединении можно использовать для изменения размера изображения с сохранением анимации.

На этот вопрос ( Конвертируйте каждый анимированный GIF-кадр в отдельный BufferedImage ) ищите ответ Алекса Ожеховского. Его код берет файл gif и преобразует его в массив ImageFrames (это класс, который он создал и который оборачивает BufferedImage). Затем посмотрите на этот код, который преобразует последовательность BufferedImages в файл GIF. (http://elliot.kroo.net/software/java/GifSequenceWriter/).

Как вы, наверное, догадались, все, что вам нужно сделать, это загрузить gif, использовать код Alex для преобразования его в массив ImageFiles / BufferedImages, использовать код Graphics2D для изменения размера каждого кадра (вам нужно добавить setImage метод к классу Алекса ImageFrame), затем используйте код Эллиота для преобразования массива в gif! Вот как выглядит моя шахта:

public static void main( String[] args )
{
  try {
     File imageFile = new File( "InputFile" );
     FileInputStream fiStream = new FileInputStream( imageFile );

     ImageFrame[] frames = readGif( fiStream );
     for( int i = 0; i < frames.length; i++ ){
        //code to resize the image
        BufferedImage image = ImageUtilities.resizeImage( frames[ i ].getImage(), newWidth, newHeight);
        frames[ i ].setImage( image );
   }

     ImageOutputStream output =
       new FileImageOutputStream( new File( "OutputFile" ) );

     GifSequenceWriter writer =
       new GifSequenceWriter( output, frames[0].getImage().getType(), frames[0].getDelay(), true );

     writer.writeToSequence( frames[0].getImage() );
     for ( int i = 1; i < frames.length; i++ ) {
        BufferedImage nextImage = frames[i].getImage();
        writer.writeToSequence( nextImage );
     }

     writer.close();
     output.close();
  }
  catch ( FileNotFoundException e ) {
     System.out.println( "File not found" );
  }
  catch ( IOException e ) {
     System.out.println( "IO Exception" );
  }
}

Однако этот код не учитывает gif-изображения с разным интервалом времени между кадрами.

4 голосов
/ 24 августа 2016

Так что я знаю, что это старое, но я нашел решение, я использую Java 8, не уверен, что он будет работать с другими версиями.

    ImageIcon image = ? (whatever/wherever your gif is)
    int width = 100;
    int height = 100;
    image.setImage(image.getImage().getScaledInstance(width, height, Image.SCALE_DEFAULT));

вы можете изменить SCALE_DEFAULT на перечисленные здесь, за исключением SCALE_SMOOTH и SCALE_AREA_AVREAGING, которые у меня не работали, были пустыми https://docs.oracle.com/javase/7/docs/api/java/awt/Image.html

...