尝试从java

时间:2017-04-23 05:55:55

标签: java javax.imageio twelvemonkeys

我需要读取一个非常大的图像文件(56000像素X 49000像素)。我需要用小矩形块读取它,所以我试着遵循这个例子:Read region from very large image file in Java

但是,我收到此错误:java.lang.IllegalArgumentException:width * height> Integer.MAX_VALUE的!

我的代码段在下面(或多或少地完全取自上面的链接):

ImageInputStream stream = null;
    try {
        stream = ImageIO.createImageInputStream(new File(this.inFile)); // File or input stream
    } catch (Exception ex) {
        Logger.getLogger(CreateTrainingSetFromImage.class.getName()).log(Level.SEVERE, null, ex);
    }
    Iterator<ImageReader> readers = ImageIO.getImageReaders(stream);

    ImageReader r = readers.next();
    System.out.println("Using reader: " + r);
    r.setInput(stream);
    try {
        System.out.println("Height = " + r.getHeight(0));
        System.out.println("Width = " + r.getWidth(0));
    } catch (IOException ex) {
        Logger.getLogger(CreateTrainingSetFromImage.class.getName()).log(Level.SEVERE, null, ex);
    }

ImageReadParam param = r.getDefaultReadParam();
Rectangle sourceRegion = new Rectangle(0, 0, 200, 200);
param.setSourceRegion(sourceRegion); // Set region

        BufferedImage image = null;
        try {
            image = r.read(0, param); // Will read only the region specified
            System.out.println("Read file " + this.inFile);
            System.out.println("Width = " + image.getWidth());
            System.out.println("Height = " + image.getHeight());
        } catch (Exception ex) {
            Logger.getLogger(CreateTrainingSetFromImage.class.getName()).log(Level.SEVERE, null, ex);
        }

我的理解是为param指定Rectangle sourceRegion将使ImageReader只读取图像的一小部分,因此我不明白导致错误的原因。任何帮助将非常感激。如果有帮助,我使用的是TwelveMonkeys ImageIO插件。

这是输出:

Using reader: com.twelvemonkeys.imageio.plugins.jpeg.JPEGImageReader@5437dd04
Height = 49429
Width = 56281
Apr 23, 2017 11:57:17 AM createtrainingsetfromimage.CreateTrainingSetFromImage    test
SEVERE: null
java.lang.IllegalArgumentException: width*height > Integer.MAX_VALUE!
at javax.imageio.ImageReader.getDestination(ImageReader.java:2840)
at com.sun.imageio.plugins.jpeg.JPEGImageReader.readInternal(JPEGImageReader.java:1066)
at com.sun.imageio.plugins.jpeg.JPEGImageReader.read(JPEGImageReader.java:1034)
at com.twelvemonkeys.imageio.plugins.jpeg.JPEGImageReader.read(JPEGImageReader.java:382)
at createtrainingsetfromimage.CreateTrainingSetFromImage.test(CreateTrainingSetFromImage.java:102)
at createtrainingsetfromimage.CreateTrainingSetFromImage.createTrainingSet(CreateTrainingSetFromImage.java:168)
at createtrainingsetfromimage.CreateTrainingSetFromImage.main(CreateTrainingSetFromImage.java:46)

1 个答案:

答案 0 :(得分:0)

getDestination基类ImageReader基类(JPEGImageReader和所有其他ImageIO读取器实现的超类)的width方法存在已知错误/限制,它计算宽度* 输入图像的高度,而不是您实际尝试读取的区域...这可以防止您阅读此类图像的一小部分。

代码如下所示,heightif ((long) width * height > Integer.MAX_VALUE) { throw new IllegalArgumentException("width*height > Integer.MAX_VALUE!"); } 参数是输入的维度:

ImageReader

在我的大多数(TwelveMonkeys ImageIO库)getDestination中,我通过使用JPEGImageReader方法的不同实现来解决此限制。但是对于com.sun....JPEGImageReader我将实际解码委托给使用原始方法的readRaster,并导致此异常。

可以使用read方法而不是getDestination(因为它不使用let mutable duplicates = false for el in (combo|>Seq.head) do let exists = Seq.exists (fun x -> x = el) (combo|>Seq.item 1) duplicates <- exists 方法)解决问题,但它需要额外的工作,并且我还没有可能测试这个。