调整动画GIF的大小,同时使用java保持动画

G.A*_*med 7 java animation gif

我在java中使用Graphics2D来调整图像大小,它与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;
}
Run Code Online (Sandbox Code Playgroud)

所以,任何线索如何在重新调整尺寸后如何保持动画GIF?谢谢.

小智 9

所以我知道这是旧的,但我找到了一个解决方案,我使用的是 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));
Run Code Online (Sandbox Code Playgroud)

您可以将 SCALE_DEFAULT 更改为此处列出的那些,除了 SCALE_SMOOTH 和 SCALE_AREA_AVREAGING 对我不起作用,它是空白的 https://docs.oracle.com/javase/7/docs/api/java/awt/Image.html


小智 6

我找到了两个源,它们在组合时可用于在保持动画的同时调整图像大小.

在这个问题上( 将每个动画GIF帧转换为单独的BufferedImage)寻找Alex Orzechowski的答案.他的代码采用gif文件并将其转换为ImageFrames数组(这是他创建的包装BufferedImage的类).然后看看这个将BufferedImages序列转换为gif文件的代码(http://elliot.kroo.net/software/java/GifSequenceWriter/).

你可能猜到,你需要做的就是上传gif,使用Alex的代码将其转换为ImageFiles/BufferedImages数组,使用你的Graphics2D代码来调整每个帧的大小(你需要为Alex's添加一个setImage方法) ImageFrame类),然后使用Elliot的代码将数组转换为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" );
  }
}
Run Code Online (Sandbox Code Playgroud)

然而,该代码不考虑具有在帧之间流逝的不同时间量的gif图像.

  • 太棒了,非常感谢。完全解决了这个问题,我现在可以调整 gif 的大小并保留动画了。唯一注意的是你应该将frames[0].getDelay()乘以10,因为在GifSequenceWriter内部它除以10(从毫秒调整) (2认同)