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

时间:2012-02-22 09:33:23

标签: 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;
}

所以,任何线索如何在重新调整大小后如何保持动画GIF? 感谢。

4 个答案:

答案 0 :(得分:6)

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

关于这个问题( Convert each animated GIF frame to a separate BufferedImage)寻找Alex Orzechowski的答案。他的代码采用gif文件并将其转换为ImageFrames数组(这是他创建的包装BufferedImage的类)。然后看看这个将BufferedImages序列转换为gif文件的代码 (http://elliot.kroo.net/software/java/GifSequenceWriter/)。

正如您可能猜到的,您需要做的就是上传gif,使用Alex的代码将其转换为ImageFiles / BufferedImages数组,使用Graphics2D代码调整每个帧的大小(您需要添加一个setImage Alex的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" );
  }
}

但是,此代码不考虑帧之间经过不同时间的gif图像。

答案 1 :(得分:4)

所以我知道这已经过时但是我找到了一个解决方案,我使用的是Java 8,不确定它是否适用于其他版本。

.card-wrapper IMG {
    border-top-left-radius: 25px;
    border-top-right-radius: 25px;
    margin: 0 0 20px;
    display: block;
    width: 100%;
    height: auto;
}

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

答案 2 :(得分:0)

Jonny March的解决方案对我不起作用,因为它仅处理和输出GIF文件的第一张图片。

这是我的解决方案,它可以在调整大小的同时保留动画。

File f = new File("path of your animated gif");
URL img = f.toURL();
ImageIcon icon = new ImageIcon(img);
//You have to convert it to URL because ImageIO just ruins the animation

int width = 100;
int height = 100;
icon.setImage(icon.getImage().getScaledInstance(width, height,Image.SCALE_DEFAULT));

答案 3 :(得分:0)

BufferedImage origBuffImg = ImageIO.read(orignalImage); int type = origBuffImg.getType() == 0? BufferedImage.TYPE_INT_ARGB : origBuffImg.getType();

          BufferedImage resizedBuffImg = new BufferedImage(width, height, type);
          Graphics2D g = resizedBuffImg.createGraphics();
          g.drawImage(origBuffImg, 0, 0, width, height, null);
          g.dispose();
         
          String newFile = orignalImage.getAbsolutePath().substring(0,orignalImage.getAbsolutePath().lastIndexOf("."))+"_"+width+"x"+height+"."+extension;
          ImageIO.write(resizedBuffImg, extension, new File(newFile));
         
          System.out.println("File created : "+newFile);