我在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? 感谢。
答案 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);