resizing animated GIF while keeping it's animation using java

11,286

Solution 1

So I know this is old but I found a solution, I am using Java 8 not sure if it will work with other versions.

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

you can change SCALE_DEFAULT to the ones listed here except for SCALE_SMOOTH and SCALE_AREA_AVREAGING didn't work for me, it was blank https://docs.oracle.com/javase/7/docs/api/java/awt/Image.html

Solution 2

I found two sources which when combined can be used to resize the image while keeping the animation.

On this question ( Convert each animated GIF frame to a separate BufferedImage ) look for the answer by Alex Orzechowski. His code takes a gif file and converts it to an array of ImageFrames (which is a class he made which wraps a BufferedImage). Then look at this code which converts a sequence of BufferedImages to a gif file ( http://elliot.kroo.net/software/java/GifSequenceWriter/ ).

As you could probably guess, all you need to do is upload the gif, use Alex's code to convert it to an array of ImageFiles/BufferedImages, use your Graphics2D code to resize each frame (you'll need to add a setImage method to Alex's ImageFrame class), then use Elliot's code to convert the array to a gif! Here is what mine looks like:

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" );
  }
}

This code, however, does not account for gif images with different amount of time elapsing between frames.

Share:
11,286
G.Ahmed
Author by

G.Ahmed

Updated on June 26, 2022

Comments

  • G.Ahmed
    G.Ahmed about 2 years

    i am using Graphics2D in java to resize images, it works perfect with jpg,png and other formats. my problem is the animated GIF images, after re-sizing the animation is gone!

    here is the method am using:

        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;
    }
    

    so, any clues how can i keep on the animated gif after re-sizing? Thanks.

  • Erich
    Erich over 9 years
    Awesome, thanks so much. Totally solved it and I can resize gifs and keep the animation now. Only note is you should multiply frames[0].getDelay() by 10 because inside GifSequenceWriter it divides by 10 (to adjust from milliseconds)
  • Vipul
    Vipul about 8 years
    It work well but takes around 200MB for gif of size 1MB and 222 frames. is there any why to reduce memory usage??
  • JakeRobb
    JakeRobb about 7 years
    This is the method I use. SCALE_SMOOTH and SCALE_AREA_AVERAGING are the same algorithm under the covers, and I can confirm that I get a blank image output if I feed it an animated GIF. Best results from SCALE_DEFAULT in that case. For other images, SCALE_SMOOTH produces somewhat nicer results.
  • drdrej
    drdrej about 5 years
    Thank yout for the Hint with the Sequence!
  • surajs1n
    surajs1n over 3 years
    please do write some explanation with your code and do intent your code properly.
  • Stefan Reich
    Stefan Reich over 2 years
    Excellent advice, this really works. Of course smoothing would be even more desirable but this is ok to get some results quickly.