为什么 ImageReader 返回不正确的 BufferedImage? [英] Why does ImageReader return incorrect BufferedImage?

查看:47
本文介绍了为什么 ImageReader 返回不正确的 BufferedImage?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

import java.awt.image.BufferedImage;导入 java.io.File;导入 java.io.IOException;导入 java.util.ArrayList;导入 java.util.Iterator;导入 java.util.List;导入 javax.imageio.ImageIO;导入 javax.imageio.ImageReader;导入 org.apache.commons.io.FileUtils;导入 org.apache.commons.io.filefilter.IOFileFilter;导入 org.apache.commons.io.filefilter.SuffixFileFilter;导入 org.apache.commons.io.filefilter.TrueFileFilter;公共类图片搜索{公共静态无效搜索(文件文件){尝试 {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());标题.flush();} catch (IOException e) {System.out.println(e);}}public static void main(String[] args) 抛出 IOException {列表<字符串>suffixes = new ArrayList();suffixes.add(".jpg");suffixes.add(".gif");suffixes.add(".bmp");suffixes.add(".png");迭代器<文件>文件 = FileUtils.iterateFiles(新文件("F:/test/"), (IOFileFilter) new SuffixFileFilter(后缀), TrueFileFilter.INSTANCE);而 (files.hasNext()) {File file = (File) files.next();图片搜索.搜索(文件);}}}

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

解决方案

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

>

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

附录:

<块引用>

有没有办法用普通图像和变化获取全像素数据?

假设已知几何图形,您应该能够在 BufferedImage 中组合第一个图像和任何后面的图像,如下所示 这里.

代码:

import java.awt.image.BufferedImage;导入 java.io.IOException;导入 java.net.URL;导入 javax.imageio.ImageIO;导入 javax.imageio.ImageReader;公共类 GifBounds {/** @see https://stackoverflow.com/questions/5688104 */public static void main(String[] args) 抛出 IOException {搜索(新网址(http://i55.tinypic.com/263veb9.gif"));}公共静态无效搜索(URL url)抛出 IOException {尝试 {ImageReader reader = ImageIO.getImageReadersBySuffix("gif").next();reader.setInput(ImageIO.createImageInputStream(url.openStream()));int i = reader.getMinIndex();而(真){BufferedImage bi = reader.read(i++);System.out.println(i+ ":" + bi.getWidth()+ ", " + bi.getHeight());}} catch (IndexOutOfBoundsException e) {//忽略}}}

控制台:

<前>1: 200, 2202: 79, 953: 77, 944: 78, 955: 79, 956: 77, 947: 78, 958: 79, 959: 77, 9410: 180, 20511: 97, 11112: 173, 20013: 174, 15514: 174, 15515: 174, 15516: 174, 15517: 174, 15518: 174, 15519: 174, 15520: 167, 20021: 97, 111

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?

解决方案

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

这篇关于为什么 ImageReader 返回不正确的 BufferedImage?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆