图像大小在JAR中返回-1,但在IDE中返回适当的大小。通过Toolkit加载的图像.... createImage(url)

时间:2014-12-01 11:42:01

标签: java image jar size bufferedimage

意图:从资源获取BufferedImage(无论是在IDE中还是在运行JAR中)。

问题:获取图像始终有效,转换为BufferedImage需要了解大小,但即使在使用MediaTracker等待后,大小也始终返回-1。在IDE中,MediaTracker之后的大小是正确的,在它之前是-1。等待while循环直到大小> -1似乎永远不会在运行JAR时结束。 (使用JDK / JRE 8尝试使用代码语言级别6和8。)

IDE中的SSCCE输出:

  

图片:sun.awt.image.ToolkitImage@15975490

     

WIDTH:-1

     

持续时间:38毫秒

     

WIDTH:32

     

BUFFEREDIMAGE:BufferedImage @ 6adede5:type = 1 DirectColorModel:   rmask = ff0000 gmask = ff00 bmask = ff amask = 0 IntegerInterleavedRaster:   width = 32 height = 32 #Bands = 3 xOff = 0 yOff = 0 dataOffset [0] 0

编辑:MediaTracker" isErrorAny()"返回false。

在运行JAR时输出SSCCE:

  

图片:sun.awt.image.ToolkitImage@2a84aee7

     

WIDTH:-1

     

持续时间:23毫秒

     

WIDTH:-1

     

线程中的异常" main"   java.lang.IllegalArgumentException:Width(-1)和height(-1)不能   是< = 0           at java.awt.image.DirectColorModel.createCompatibleWritableRaster(Unknown   资源)           at java.awt.image.BufferedImage。(Unknown Source)           at ImageSizeProblem.createBufferedImageFromImage(ImageSizeProblem.java:82)           在ImageSizeProblem.main(ImageSizeProblem.java:26)

编辑:MediaTracker" isErrorAny()"返回 true 。但我无法找出错误是什么 - 同时,图像 正确加载,因为它可以通过从中生成ImageIcon在JToolBar中成功使用。 (我已经尝试滥用ImageIcon的getIconWidth()或getImage()方法 - 它们根本没有带来任何改进。)

SSCCE:

import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.net.URL;

public class ImageSizeProblem {

    public static void main(final String[] args) {

        final Image img = createImageFromResource("test.png");

        System.out.println("IMAGE: " + img);
        System.out.println("WIDTH: " + img.getWidth(null));

        final long startTime = System.currentTimeMillis();
        waitForImage(img);
        final long duration = System.currentTimeMillis() - startTime;
        System.out.println("\nDURATION: " + duration + " ms");

        System.out.println("\nWIDTH: " + img.getWidth(null));

        final BufferedImage buffImg = createBufferedImageFromImage(img, false);
        System.out.println("\nBUFFEREDIMAGE: " + buffImg);

        System.exit(0);
    }

    private static Image createImageFromResource(final String resourceFileName_dontForgetToAddItsFolderToClasspath) {

        final Toolkit kit = Toolkit.getDefaultToolkit();
        final URL url = ClassLoader.getSystemResource(resourceFileName_dontForgetToAddItsFolderToClasspath);
        if (url != null) {
            final Image img = kit.createImage(url);
            if (img == null) {
                System.err.println("Image resource could not be loaded.");
                return null;
            }
            return img;
        } else {
            System.err.println("Image resource not found.");
            return null;
        }
    }

    private static boolean waitForImage(final Image img) {
        final MediaTracker mediaTracker = new MediaTracker(new JPanel());
        mediaTracker.addImage(img, 1);
        try {
            mediaTracker.waitForID(1);
        } catch (InterruptedException ex) {
            ex.printStackTrace();
        }
        return !mediaTracker.isErrorAny();
    }


    // improved version of http://stackoverflow.com/a/13605411/3500521
    private static BufferedImage createBufferedImageFromImage(final Image img, final boolean withTransparency) {

        if (img instanceof BufferedImage) {
            return (BufferedImage) img;
        } else if (img == null) {
            return null;
        }

        final int w = img.getWidth(null);
        final int h = img.getWidth(null);

        final BufferedImage bufferedImage;
        if (withTransparency) {
            bufferedImage = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
        } else {
            bufferedImage = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
        }

        final Graphics2D g = bufferedImage.createGraphics();
        g.drawImage(img, 0, 0, null);
        g.dispose();
        return bufferedImage;
    }
}

请注意,用于测试的图像是通过JToolBar中的新ImageIcon(图像)在另一个应用程序中成功加载和使用的。从ImageIcon获取大小也会返回-1,也来自ImageIcon.getImage()返回的图像。

1 个答案:

答案 0 :(得分:0)

该死。

问题在于路径深度。

我也试过Avira,因为问题在技术上是一个程序正在访问它自己的文件,这看起来很可疑,但是当Avira卸载时,我尝试在不同位置使用较短路径的可执行文件,一切都像魅力。

我告诉你,我们还处在他妈的石器时代。