为什么ImageReader返回错误的BufferedImage?

我试图访问21帧的动画GIF图像,然后读取第12帧(因为它从0开始?)帧。

import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import javax.imageio.ImageIO; import javax.imageio.ImageReader; import org.apache.commons.io.FileUtils; import org.apache.commons.io.filefilter.IOFileFilter; import org.apache.commons.io.filefilter.SuffixFileFilter; import org.apache.commons.io.filefilter.TrueFileFilter; public class PictureSearch { public static void search(File file) { try { ImageReader reader = (ImageReader) ImageIO.getImageReadersBySuffix("gif").next(); reader.setInput(ImageIO.createImageInputStream(file), false); BufferedImage caption = reader.read(12); System.out.println(caption.getHeight()); System.out.println(caption.getWidth()); caption.flush(); } catch (IOException e) { System.out.println(e); } } public static void main(String[] args) throws IOException { List suffixes = new ArrayList(); suffixes.add(".jpg"); suffixes.add(".gif"); suffixes.add(".bmp"); suffixes.add(".png"); Iterator files = FileUtils.iterateFiles(new File( "F:/test/"), (IOFileFilter) new SuffixFileFilter( suffixes), TrueFileFilter.INSTANCE); while (files.hasNext()) { File file = (File) files.next(); PictureSearch.search(file); } } } 

读者应该给我一个高度为220和宽度为200的缓冲图像(如果忽略图像周围的白色区域,则为高度205和宽度188)。 但它做的是它给我一个高度155和宽度174的图像,这是荒谬的,因为我三重检查,框架12是高度220和宽度200.我在读取框架时是否正确地做了一切?

示例中的矩形似乎是一个表示图像序列更改部分的框架,从1开始。在Gimp中打开文件以查看。

在此处输入图像描述

附录:它看起来像是一个旨在优化渲染的function 。 猜测,我会说你可以依赖图像编号getMinIndex() ; 后面的帧似乎包含在第一帧中。

附录:

有没有办法获得正常图像和变化的全像素数据?

假设已知几何体,您应该能够将第一个图像与BufferedImage任何一个图像组合在一起,如下所示。

码:

 import java.awt.image.BufferedImage; import java.io.IOException; import java.net.URL; import javax.imageio.ImageIO; import javax.imageio.ImageReader; public class GifBounds { /** @see https://stackoverflow.com/questions/5688104 */ public static void main(String[] args) throws IOException { search(new URL("http://i55.tinypic.com/263veb9.gif")); } public static void search(URL url) throws IOException { try { ImageReader reader = ImageIO.getImageReadersBySuffix("gif").next(); reader.setInput(ImageIO.createImageInputStream(url.openStream())); int i = reader.getMinIndex(); while (true) { BufferedImage bi = reader.read(i++); System.out.println(i + ": " + bi.getWidth() + ", " + bi.getHeight()); } } catch (IndexOutOfBoundsException e) { // ignored } } } 

安慰:

 1:200,220
 2:79,95
 3:77,94
 4:78,95
 5:79,95
 6:77,94
 7:78,95
 8:79,95
 9:77,94
 10:180,205
 11:97,111
 12:173,200
 13:174,155
 14:174,155
 15:174,155
 16:174,155
 17:174,155
 18:174,155
 19:174,155
 20:167,200
 21:97,111

代码1

 import java.net.URL; import java.awt.Image; import javax.imageio.ImageIO; class GetGifSize { public static void main(String[] args) throws Exception { URL urlToImage = new URL("http://i55.tinypic.com/263veb9.gif"); Image image = ImageIO.read(urlToImage); System.out.println( "Image size is " + image.getWidth(null) + "x" + image.getHeight(null) ); } } 

产量

 Image size is 200x220 

代码2

trashgod发布的代码变体。

 import java.awt.image.BufferedImage; import java.io.IOException; import java.net.URL; import javax.imageio.ImageIO; import javax.imageio.ImageReader; public class GifBounds { /** @see http://stackoverflow.com/questions/5688104 */ public static void main(String[] args) throws IOException { search(new URL("http://i55.tinypic.com/263veb9.gif")); } public static void search(URL url) throws IOException { ImageReader reader = ImageIO.getImageReadersBySuffix("gif").next(); reader.setInput(ImageIO.createImageInputStream(url.openStream())); int i = reader.getMinIndex(); int offset = i-0; int count = reader.getNumImages(true); System.out.println("Image count: " + count); for (int ii=i; ii<(count-i); ii++) { BufferedImage bi = reader.read(ii); System.out.println(ii + offset + ": " + bi.getWidth() + ", " + bi.getHeight()); } } } 

顺便说一句,我认为你应该将trashgod的答案标记为两个答案的正确答案。

它是第一个找到问题的真正核心。 而且你必须用屏幕截图来回答问题。 这将是“整个9码”。