如何解决java.lang.IllegalArgumentException:Width(-1)和height(-1)不能是< = 0?

时间:2016-01-19 02:47:18

标签: java bufferedimage illegalargumentexception

我花了最后几个小时试图解决下面的堆栈跟踪。通过对SO和Google的重大研究,我理解异常可能意味着几件事:

  • 程序无法使用提供的路径找到所请求的图像;

  • 在生成宽度和高度之后,渲染图像,为什么它等于0 ...

我错过了什么吗?我无法弄清楚如何解决这个问题......

堆栈

  

线程“main”中的异常java.lang.IllegalArgumentException:Width   (-1)和高度(-1)不能<= 0   java.awt.image.DirectColorModel.createCompatibleWritableRaster(DirectColorModel.java:1016)     在java.awt.image.BufferedImage。(BufferedImage.java:331)at   tp6.Interface.toBufferedImage(Interface.java:157)at   tp6.Interface。(Interface.java:36)at   tp6.Interface.main(Interface.java:171)

tp6.Interface.toBufferedImage(Interface.java:157):

public BufferedImage toBufferedImage(Image image) {

        if( image instanceof BufferedImage ) {

                return( (BufferedImage)image );
        } else {

                image = new ImageIcon(image).getImage();

                BufferedImage bufferedImage = new BufferedImage(
                                                      image.getWidth(null),
                                                      image.getHeight(null),
                                                      BufferedImage.TYPE_INT_RGB );
                Graphics g = bufferedImage.createGraphics();
                g.drawImage(image,0,0,null);
                g.dispose();
                return( bufferedImage );
        }
}

tp6.Interface。(Interface.java:36)

//IMAGE JPANEL
Image map=new ImageIcon("images/main.gif").getImage();
    Image digi=new ImageIcon("images/digits.gif").getImage();
    BufferedImage mapmodifiable= toBufferedImage(map);
    BufferedImage digits= toBufferedImage(digi);

tp6.Interface.main(Interface.java:171)

public static void main(String[] args)
    {
        Window windowintro = new Window( 440, 400, 1);
        //INTERFACE GRAPHIC
        Interface graphic=new Interface();

        graphic.addWindowListener(new WindowAdapter() {
                        @Override
            public void windowClosing(WindowEvent evt) {
                System.exit(0);
            }
        });
    }

3 个答案:

答案 0 :(得分:2)

已经解释了异常的原因,Image方法getWidth(null)getHeight(null)在图像尺寸尚未知晓时返回-1。这是实现的,因为Java中的旧Image API是异步并从当前线程加载图像资源。在您写作时,也可能因为找不到图像而发生。

但是,由于您希望将图像用作BufferedImage s(可能是因为您希望在某个阶段修改它们),因此使用更新的同步 ImageIO API。在大多数情况下,代码将更清晰,更容易理解,更重要的是;如果无法找到/加载图片,您将立即收到错误消息。

所以,而不是:

Image map = new ImageIcon("images/main.gif").getImage();
BufferedImage mapmodifiable = toBufferedImage(map);

您可以这样做:

BufferedImage mapmodifiable = ImageIO.read(new File("images/main.gif"));

PS: 可以将Image转换为BufferedImage,就像使用toBufferedImage方法一样,使用ImageIcon.getImage(..) < em>应确保图像已预加载(ImageIcon内部使用MediaTracker进行预加载)。但是,正如我上面所说,旧的Image API在错误反馈方面不是很好,所以很可能问题是找不到您的图像。

答案 1 :(得分:1)

我也有这个问题。我通过添加一行代码解决了这个问题。在你的toBufferedImage()方法的第一行中,你可以放

while(image.getWidth() == -1);

此行将保持循环,直到除了-1之外的getWidth()中有一个值。

答案 2 :(得分:0)

我发现了this有关您问题的问题。也许您正在使用异步方式加载图像。这意味着,当您致电getWidth(null)getHeight(null)时,可能尚未加载图片。由于此时可能未加载图像,因此可能还不知道宽度和高度。这就是返回-1的原因。

如果您使用Thread.sleep(1000)添加一些延迟,也许您会得到正确的结果。我没有调查它,但它绝对不是一个好的解决方案。在某些系统上你可能睡得不够长。在其他系统上,你可能会睡不必要多久。由于我不太了解规范,如果Thread.sleep阻止进程读取图像(有人知道吗?),它甚至可能是Java的有效实现。

我会看到两种可用于解决问题的方法:

第一个解决方案

一种解决方案是使用阻塞IO加载映像。就像在linked question的答案中描述的那样。

第二种解决方案

另一种解决方案是使用ImageObserver

int width = getWidth(new ImageObserver() {
    @Override
    public boolean imageUpdate(Image img, int infoflags, int x, int y, int width, int height) {
        // TODO use the width when the image is loaded and the size is known
    }
});
if (width != -1) {
    // TODO use the width, it is already known
}