resizing animated GIF while keeping it's animation using java
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.
G.Ahmed
Updated on June 26, 2022Comments
-
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 over 9 yearsAwesome, 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 about 8 yearsIt work well but takes around 200MB for gif of size 1MB and 222 frames. is there any why to reduce memory usage??
-
JakeRobb about 7 yearsThis 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 about 5 yearsThank yout for the Hint with the Sequence!
-
surajs1n over 3 yearsplease do write some explanation with your code and do intent your code properly.
-
Stefan Reich over 2 yearsExcellent advice, this really works. Of course smoothing would be even more desirable but this is ok to get some results quickly.