快捷搜索:

如何在Java应用程序中读取8位和24位MicrosoftWindow

在 Java 利用法度榜样中加载位图文件的慢慢指南

作者:Jeff West 和 John D. Mitchell

择要

今朝,标准的 getImage() 措施仅支持 GIF 和 JPEG 图像。只管存在用于读取 PNG(可移植收集图形)款式的 Java 例程,但我们还没据说过有用于读取 Microsoft Windows 位图图像的涉猎法度榜样。Jeff West 撰写的这篇技术供给了加载 Windows 位图图像的代码。

Java 确当前发行版并不正式支持在 Java 利用法度榜样中读取 Microsoft Windows 位图文件。但别担心,我们有法子办理这个问题!这篇技术将阐明若何完成这一义务 -- 我们首先阐明读取 Microsoft Windows 文件款式的基础步骤。

Windows DIB(设备自力的位图)文件款式对照简单。与纯位图款式不合,DIB 款式保留着用于在内存中存储图像的明确信息。问题是图像款式的变体如斯之多(1 位、4 位、8 位和 16 位,以及其他款式)。本篇 Java 技术中供给的办理规划只处置惩罚 8 位和 24 位两种款式。这两种款式代表了最常见的变体。

不管是哪种 Windows DIB 子类型,这种文件款式老是由 14 位文件头和 40 位信息头组成。这两个标头正确包孕有关文件的存储内容和存储序次的信息。有关标头中每一项切实着实切含义,请参考 Microsoft Software Development Kit (SDK)。文件另外部分的内容随信息头中数据的不合而不合。

我们看一下本文要处置惩罚的两种子类型。24 位款式很简单:RGB(红-绿-蓝)颜色值(3 个字节,并按 BGR 排序)紧接在信息头之后。然则,每个扫描行都被补足到 4 个字节。按照阐明文档(请参阅 Microsoft SDK)的说法,这种“补足”是为了优化 Windows 位图绘图 API。同时,底部的扫描行是文件中的第一项内容 -- 是以相对通俗的图形坐标系统(其矢量偏向的正向分手为向下和向右)而言,必须从后向前读取图像。

8 位子类型因为在信息头和象素数据之间插入调色板信息而繁杂化。是以,每个象素条款只是进入 24 位 RGB 颜色的调色板数组的一个 8 位索引。在象素信息中,每个扫描行同样被补足到 4 个字节。

请留意,本文供给的位图图像加载措施不支持对压缩位图图像进行解压缩。实际上,这个例程以致不寻求这种可能性!假如碰到压缩 Windows DIB 文件,该例程肯定会孕育发生非常。Windows SDK 中有对压缩 Windows DIB 款式的阐明。

至于机能,在运行 Microsoft Windows 95 的 486-DX2-66MHz 系统上,该例程读取 24 位 640 x 480 的文件(大年夜约 920 千字节)所需的光阴不跨越 10 秒。应用 BufferedInputStream 而不是 FileInputStream 可显着前进机能。

以下例程读取两种文件款式中的任一种,并天生一个 Image 图像。以下代码并未包孕周全的差错和非常处置惩罚,以避免使该例程加倍繁杂。您总可用 Windows Paint 法度榜样对不支持的 Windows DIB 子类型进行转换。

/**

loadbitmap() 措施由 Windows C 代码转换而来。

只能读取未压缩的 24 位和 8 位图像。已在

Windows 95 上用 Microsoft Paint 保存的图像

对它进行了测试。假如图像不是 24 位或 8 位图像,

该法度榜样回绝进行任何考试测验。我预测假如先用 1100,

然后用 0011 对字节履行掩码操作,则也可将 4 位

图像包括在内。我实际上对这些图像不感兴趣。

假如考试测验读取压缩图像,该例程可能掉败,并孕育发生

一个 IOException 非常。假如变量 ncompression

不为 0,则表示已颠末压缩。

参数:

sdir 和 sfile 是 FileDialog 的

getDirectory() 和 getFile() 措施的结果。

返回值:

Image 工具,牢记要反省 (Image)null !!!!

*/

public Image loadbitmap (String sdir, String sfile)

{

Image image;

System.out.println("loading:"+sdir+sfile);

try

{

FileInputStream fs=new FileInputStream(sdir+sfile);

int bflen=14; // 14 字节 BITMAPFILEHEADER

byte bf[]=new byte[bflen];

fs.read(bf,0,bflen);

int bilen=40; // 40 字节 BITMAPINFOHEADER

byte bi[]=new byte[bilen];

fs.read(bi,0,bilen);

// 解释数据。

int nsize = (((int)bf[5]&0xff) 0)

{

nNumColors = nclrused;

}

else

{

nNumColors = (1&0xff)> 3);

nsizeimage *= nheight;

System.out.println("nsizeimage (backup) is"+nsizeimage);

}

// 读取调色板颜色。

int npalette[] = new int [nNumColors];

byte bpalette[] = new byte [nNumColors*4];

fs.read (bpalette, 0, nNumColors*4);

int nindex8 = 0;

for (int n = 0; n http://www-900.ibm.com/developerWorks/cn/java/jw-tips/tip043/index.shtml

您可能还会对下面的文章感兴趣: