Why does ImageReader return incorrect BufferedImage?

亡梦爱人 提交于 2019-11-28 13:43:06
trashgod

The rectangle in your example appears to be a frame representing the changed portion of the image sequence, starting from 1. Open the file in Gimp to see.

Addendum: It looks like a feature intended to optimize rendering. At a guess, I'd say you could rely on the bounds of image number getMinIndex(); later frames appear to be subsumed in the first.

Addendum:

is there a way to get the full pixel data with the normal image and changes?

Assuming known geometry, you should be able to combine the first image and any later one in a BufferedImage, as shown here.

Code:

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
        }
    }
}

Console:

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

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

Output

Image size is 200x220

Code 2

A variant of the code posted by 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());
        }
    }
}

As an aside, I think you should mark trashgod's answer correct of the two answers.

It was first to get to the real core of the problem. And you gotta' love an answer with screen-shots. That's going 'the whole 9 yards'.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!