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

发布于 2025-01-08 12:41:22 字数 1144 浏览 1 评论 0原文

我在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 吗? 谢谢。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

深空失忆 2025-01-15 12:41:22

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

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

罪#恶を代价 2025-01-15 12:41:22

我发现了两个源,将它们组合起来可用于在保留动画的同时调整图像大小。

关于这个问题(
将每个动画 GIF 帧转换为单独的 BufferedImage )查找亚历克斯·奥尔泽霍夫斯基的回答。他的代码采用一个 gif 文件并将其转换为 ImageFrame 数组(这是他创建的一个包装 BufferedImage 的类)。然后看看这段代码,它将 BufferedImages 序列转换为 gif 文件
( http://elliot.kroo.net/software/java/GifSequenceWriter/ )。

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

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

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.

猥︴琐丶欲为 2025-01-15 12:41:22

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

Jonny March's solution did not work for me because it processes and outputs only the first image of GIF file.

Here is my solution, it keeps the animation while resizing.

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));
短叹 2025-01-15 12:41:22

BufferedImage origBuffImg = ImageIO.read(orignalImage);
int 类型 = 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);

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);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文