我有一个位图文件test3.bmp
,可以使用经过测试的每个图像查看器进行查看和编辑。
也就是说,我无法将其读入Java应用程序。如果我在MS Paint中编辑BMP,将其保存,撤消更改并保存(test3_resaved.bmp
),则我具有相同的图像,但是文件大小不同。不同的文件大小与我无关...什么是我的应用程序可以读取重新保存的文件。
谁能启发我为什么一个图像可以与我的代码一起使用,而另一个图像却不能呢?
图像文件:
这是一个最小的测试应用程序:
package Test;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
@SuppressWarnings("serial")
public class Test extends JFrame {
private ImageIcon imageIcon;
public Test(String filename) throws IOException {
super();
BufferedImage image = javax.imageio.ImageIO.read(new File(filename));
imageIcon = new ImageIcon(image);
setVisible(true);
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
repaint();
}
public void paint(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
setSize(imageIcon.getIconWidth(), imageIcon.getIconHeight());
if (imageIcon != null)
g2d.drawImage(imageIcon.getImage(), 0, 0, this);
}
/**
* @param args
*/
public static void main(String[] args) {
try {
if (args.length > 0)
new Test(args[0]);
else
System.out.println("usage - specify image filename on command line");
}
catch (Throwable t) {
t.printStackTrace();
}
}
}
最佳答案
(扩大我的评论)
问题归结为:人们通常认为以下命令给出的“格式”:
ImageIO.getReaderFileSuffixes();
受Java支持。
但这不是应该被理解/理解的方式,因为那根本不是它的工作方式。
错误:“ImageIO可以读取使用这些格式之一编码的任何文件”
正确:“ImageIO无法读取使用不是这些格式之一的格式编码的图像”
但是,这对出现在该列表中的格式有何说明?好吧,这很棘手。
例如,该列表通常返回“PNG”和“BMP”(以及其他格式)。但是没有“一个” PNG和“一个” BMP。明天我可以使用一种“有效的” PNG(子)格式,该格式会很好,但是没有一个PNG解码器可以解码(必须经过验证并接受:但是一旦被接受,它将“破坏所有现有的PNG解码器)。幸运的是,对于PNG图片而言,问题还算不错。
BMP格式非常复杂。您是否可以进行压缩(这可以解释您所看到的文件大小的变化)。您可以使用各种标题(长度不同,也可以解释您看到的不同文件大小)。哎呀,BMP实际上是如此复杂,以至于您可以将PNG编码的像素嵌入BMP“ shell ”中。
BMP文件基本上有两种有问题的类型:
创建Java解码器后出现的BMP变体
“错误”在于认为存在一种PNG或一种BMP格式。两种格式(以及其他图像格式)实际上都是“可扩展的”。每当出现新的变体时,它就有可能破坏中的任何解码器。
因此,您的情况是这样的:
现在实际解决您的问题:以我的经验,像ImageMagick这样的图像库比默认的Java ImageIO API能够读取更多的图片,因此我将看看ImageMagick周围的其他图像库或包装器。
这些库通常也进行更新,以支持更新的变体和格式,比Java快得多。例如,相当多的图像处理库已经支持Google令人惊叹的WebP格式(在无损+半透明图像上比PNG好28%到34%),但是在执行ImageIO时我并不屏息。阅读(someWebPpicture)...
另一种选择是使用PNG:即使理论上可以扩展PNG,您也不太可能在野外找到“不受支持的” PNG。对于BMP来说,这太普遍了。