Java 为什么';t ImageIO读取BMP文件,直到它重新保存在MS Paint中?
我有一个位图文件,Java 为什么';t ImageIO读取BMP文件,直到它重新保存在MS Paint中?,java,image,bmp,Java,Image,Bmp,我有一个位图文件,test3.bmp,我可以用我测试过的每个图像查看器查看和编辑它 也就是说,我无法将其读入Java应用程序。如果我在MS Paint中编辑BMP,保存它,撤消更改,然后保存它(test3\u resaved.BMP),我会得到相同的图像,但文件大小不同。不同的文件大小与我无关。。。我的应用程序可以读取重新保存的文件 有谁能告诉我为什么一个图像可以与我的代码一起工作,而另一个不能 图像文件: 以下是一个最小的测试应用程序: package Test; import ja
test3.bmp
,我可以用我测试过的每个图像查看器查看和编辑它
也就是说,我无法将其读入Java应用程序。如果我在MS Paint中编辑BMP,保存它,撤消更改,然后保存它(test3\u 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();
}
}
}
这里有一些示例代码将枚举JDK支持的图像格式 高级图像工具包支持BMP,但我知道它也有一些基本JDK现在也支持的东西。因此,如果两者都支持,那么JAI的支持可能更全面。但这似乎不太可能,因为这没有多大意义。哦,是太阳 如果您使用的是JDK 6,那么肯定可以使用PNG(更便于携带),您可以转换图像吗?IIRC MS Paint将保存一个png。(根据我的评论展开) 问题归结为:人们通常认为以下命令给出的“格式”:
ImageIO.getReaderFileSuffixes();
Java支持的
但这不是应该如何阅读/理解的,因为这根本不是它的工作原理
错误:“ImageIO可以读取使用以下格式之一编码的任何文件”
更正:“ImageIO无法读取非这些格式编码的图像”
但是现在,对于列表中出现的格式,这意味着什么呢?好。。。这会变得棘手
例如,该列表通常同时返回“PNG”和“BMP”(以及其他格式)。但是没有“一个”PNG和“一个”BMP。明天我可以带上一个“有效”的PNG(sub)格式,这很好,但是没有一个PNG解码器可以解码(它必须被验证和接受:但一旦被接受,它将“破坏”所有现有的PNG解码器)。幸运的是,对于PNG图片来说,问题并不太严重
BMP格式非常复杂。您可以进行压缩,也可以不进行压缩(这可以解释您所看到的文件大小的变化)。您可以有不同的头文件(长度不同,这也可以解释您所看到的文件大小的不同)。见鬼,BMP实际上是如此复杂,以至于我认为可以将PNG编码的像素嵌入BMP“外壳”中
基本上有两种有问题的BMP文件类型:
- 创建Java解码器后出现的BMP变体
另一个选择是使用PNG:即使理论上PNG可以扩展,但在野外也不太可能找到“不受支持”的PNG。对于BMP来说,这太普遍了。我用自己的Java BMP解码器测试了这两幅图像。它还转储图像的一些信息。我发现原来的是一个32位的bmp,而重新保存的是一个24位的。所以我假设imageio bmp阅读器无法正确处理32位bmp 更新:为了证实我很久以前的猜测,我再次测试了图像,但仍然有问题。问题是没有显示图像,原因是Java ImageIO认为图像是完全透明的。以下是Java ImageIO创建的BuffereImage的转储:
DirectColorModel: rmask=ff0000 gmask=ff00 bmask=ff amask=ff000000
IntegerInterleavedRaster: width = 494 height = 516 #Bands = 4 xOff = 0 yOff = 0
dataOffset[0] 0
java.awt.image.SinglePixelPackedSampleModel@80809ee
我们可以在这里看到,有4个带表示Java ImageIO解释的RGBA。事实上,对于32位Windows BMP图像,第四个频带或第四个字节不适用于alpha通道。它只是垃圾,或者使它双字对齐
一个Windows 3.x BMP解码器和更多信息,这里有许多不同类型的BMP文件。可能您的MS Paint可以读取原始格式,但在保存文件时正在使用其他BMP标题/编码。我确信Java绝对不能读取所有的BMP文件(很少有BMP阅读器可以)。恰好Java支持MS Paint输出的特定类型的BMP。为什么是BMP?如果你想要无损,PNG会是一个选项吗?这里的问题和“Roman B.”一样。。。BMP文件的链接无法工作。你可以用hexd