2012-02-22 97 views
5

我使用Java中的Graphics2D来调整图像大小,它适用于JPG,PNG和其他格式。 我的问题是动画GIF图像,重新调整大小后动画不见了!调整动画GIF的大小,同时保持它的动画使用java

这里的方法我用:

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

我发现两个来源,当它们结合时可以用来在保持动画的同时调整图像大小。

在这个问题上( Convert each animated GIF frame to a separate BufferedImage)寻找由Alex Orzechowski答案。他的代码需要一个gif文件并将其转换为一个ImageFrame(这是他制作的一个包装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

真棒,非常感谢。完全解决了它,我可以调整GIF动画并保持动画。唯一值得注意的是你应该将帧[0] .getDelay()乘以10,因为在GifSequenceWriter中它除以10(从毫秒调整) – Erich 2014-12-29 15:57:39

+0

它工作良好,但对于1MB和222帧的大小的gif需要大约200MB。有没有什么为什么要减少内存使用量? – Vipul 2016-04-18 15:02:14

1

所以我知道这是旧的,但我找到了一个解决方案,我使用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

+0

这是我使用的方法。 SCALE_SMOOTH和SCALE_AREA_AVERAGING是封面下的相同算法,如果我为它提供动画GIF,我可以确认获得空白图像输出。在这种情况下SCALE_DEFAULT的最佳结果。 对于其他图像,SCALE_SMOOTH产生更好的结果。 – JakeRobb 2017-05-10 18:08:59