意图:从资源获取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()返回的图像。
答案 0 :(得分:0)
该死。
问题在于路径深度。
我也试过Avira,因为问题在技术上是一个程序正在访问它自己的文件,这看起来很可疑,但是当Avira卸载时,我尝试在不同位置使用较短路径的可执行文件,一切都像魅力。
我告诉你,我们还处在他妈的石器时代。