为什么 ImageReader 返回不正确的 BufferedImage?

发布于 2024-11-02 06:25:02 字数 1794 浏览 6 评论 0原文

我正在尝试访问具有 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<String> suffixes = new ArrayList<String>();
        suffixes.add(".jpg");
        suffixes.add(".gif");
        suffixes.add(".bmp");
        suffixes.add(".png");

        Iterator<File> 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。 我在读取帧时所做的一切都正确吗?

I'm trying to access a animated GIF image with 21 frames and then read the 12th (cause it starts at 0?) frame.

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<String> suffixes = new ArrayList<String>();
        suffixes.add(".jpg");
        suffixes.add(".gif");
        suffixes.add(".bmp");
        suffixes.add(".png");

        Iterator<File> files = FileUtils.iterateFiles(new File(
                "F:/test/"), (IOFileFilter) new SuffixFileFilter(
                suffixes), TrueFileFilter.INSTANCE);

        while (files.hasNext()) {
            File file = (File) files.next();
            PictureSearch.search(file);
        }

    }
}

The reader should return me a buffered image with height 220 and width 200 (or height 205 and width 188 if it ignores white fields around the image).
But what it does is it returns me a image of height 155 and width 174 what is absurd because i triple checked and the frame 12 is height 220 and width 200.
Am I doing everything correctly in reading the frames?

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

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

发布评论

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

评论(2

过期情话 2024-11-09 06:25:02

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

在此处输入图像描述

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

附录:

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

假设几何形状已知,您应该能够将第一个图像和后面的任何图像合并到 BufferedImage 中,如此处< /a>.

代码:

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

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.

enter image description here

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
ゝ杯具 2024-11-09 06:25:02

代码 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());
        }
    }
}

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

首先要触及问题的真正核心。你一定会喜欢带有屏幕截图的答案。这就是“整个 9 码”。

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'.

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