说三道四技术文摘-感悟人生的经典句子
说三道四 > 文档快照

如何用java编写BMP的显示程序???

编辑:说三道四文库 发布时间:2017-06-25 11:35
HTML文档下载 WORD文档下载 PDF文档下载
前提:尽量不使用JNI,不使用vj编写
请指教!
可以 阿 你要不要 阿 ??
给分的阿 !!
我可以给你 代码 
星期一给你
谢谢两位
请告诉我大概的方法,譬如用到什么类库和API
当然,附源程序更好
mail to :wdfriend@263.net
谢了先
ava 技巧 43:如何在 Java 应用程序中读取 8 位和 24 位 Microsoft Windows 位图
在 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);

     // 解释数据。
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int nsize = (((int)bf[5]&0xff)<<24)
&nbsp;&nbsp;| (((int)bf[4]&0xff)<<16)
&nbsp;&nbsp;| (((int)bf[3]&0xff)<<8)
&nbsp;&nbsp;| (int)bf[2]&0xff;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("File type is :"+(char)bf[0]+(char)bf[1]);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("Size of file is :"+nsize);

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int nbisize = (((int)bi[3]&0xff)<<24)
&nbsp;&nbsp;| (((int)bi[2]&0xff)<<16)
&nbsp;&nbsp;| (((int)bi[1]&0xff)<<8)
&nbsp;&nbsp;| (int)bi[0]&0xff;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("Size of bitmapinfoheader is :"+nbisize);

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int nwidth = (((int)bi[7]&0xff)<<24)
&nbsp;&nbsp;| (((int)bi[6]&0xff)<<16)
&nbsp;&nbsp;| (((int)bi[5]&0xff)<<8)
&nbsp;&nbsp;| (int)bi[4]&0xff;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("Width is :"+nwidth);

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int nheight = (((int)bi[11]&0xff)<<24)
&nbsp;&nbsp;| (((int)bi[10]&0xff)<<16)
&nbsp;&nbsp;| (((int)bi[9]&0xff)<<8)
&nbsp;&nbsp;| (int)bi[8]&0xff;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("Height is :"+nheight);

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int nplanes = (((int)bi[13]&0xff)<<8) | (int)bi[12]&0xff;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("Planes is :"+nplanes);

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int nbitcount = (((int)bi[15]&0xff)<<8) | (int)bi[14]&0xff;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("BitCount is :"+nbitcount);

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 查找表明压缩的非零值
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int ncompression = (((int)bi[19])<<24)
&nbsp;&nbsp;| (((int)bi[18])<<16)
&nbsp;&nbsp;| (((int)bi[17])<<8)
&nbsp;&nbsp;| (int)bi[16];
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("Compression is :"+ncompression);

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int nsizeimage = (((int)bi[23]&0xff)<<24)
&nbsp;&nbsp;| (((int)bi[22]&0xff)<<16)
&nbsp;&nbsp;| (((int)bi[21]&0xff)<<8)
&nbsp;&nbsp;| (int)bi[20]&0xff;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("SizeImage is :"+nsizeimage);

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int nxpm = (((int)bi[27]&0xff)<<24)
&nbsp;&nbsp;| (((int)bi[26]&0xff)<<16)
&nbsp;&nbsp;| (((int)bi[25]&0xff)<<8)
&nbsp;&nbsp;| (int)bi[24]&0xff;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("X-Pixels per meter is :"+nxpm);

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int nypm = (((int)bi[31]&0xff)<<24)
&nbsp;&nbsp;| (((int)bi[30]&0xff)<<16)
&nbsp;&nbsp;| (((int)bi[29]&0xff)<<8)
&nbsp;&nbsp;| (int)bi[28]&0xff;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("Y-Pixels per meter is :"+nypm);

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int nclrused = (((int)bi[35]&0xff)<<24)
&nbsp;&nbsp;| (((int)bi[34]&0xff)<<16)
&nbsp;&nbsp;| (((int)bi[33]&0xff)<<8)
&nbsp;&nbsp;| (int)bi[32]&0xff;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("Colors used are :"+nclrused);

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int nclrimp = (((int)bi[39]&0xff)<<24)
&nbsp;&nbsp;| (((int)bi[38]&0xff)<<16)
&nbsp;&nbsp;| (((int)bi[37]&0xff)<<8)
&nbsp;&nbsp;| (int)bi[36]&0xff;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("Colors important are :"+nclrimp);

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (nbitcount==24)
&nbsp;&nbsp;{
&nbsp;&nbsp;// 24 位格式不包含调色板数据,但扫描行被补足到
&nbsp;&nbsp;// 4 个字节。
&nbsp;&nbsp;int npad = (nsizeimage / nheight) - nwidth * 3;
&nbsp;&nbsp;int ndata[] = new int [nheight * nwidth];
&nbsp;&nbsp;byte brgb[] = new byte [( nwidth + npad) * 3 * nheight];
&nbsp;&nbsp;fs.read (brgb, 0, (nwidth + npad) * 3 * nheight);
&nbsp;&nbsp;int nindex = 0;
&nbsp;&nbsp;for (int j = 0; j < nheight; j++)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for (int i = 0; i < nwidth; i++)
&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;ndata [nwidth * (nheight - j - 1) + i] =
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(255&0xff)<<24
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| (((int)brgb[nindex+2]&0xff)<<16)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| (((int)brgb[nindex+1]&0xff)<<8)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| (int)brgb[nindex]&0xff;
&nbsp;&nbsp;&nbsp;// System.out.println("Encoded Color at ("
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;+i+","+j+")is:"+nrgb+" (R,G,B)= ("
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;+((int)(brgb[2]) & 0xff)+","
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;+((int)brgb[1]&0xff)+","
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;+((int)brgb[0]&0xff)+")");
&nbsp;&nbsp;&nbsp;nindex += 3;
&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;nindex += npad;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;image = createImage
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;( new MemoryImageSource (nwidth, nheight,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ndata, 0, nwidth));
&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else if (nbitcount == 8)
&nbsp;&nbsp;{
&nbsp;&nbsp;// 必须确定颜色数。如果 clrsused 参数大于 0,
&nbsp;&nbsp;// 则颜色数由它决定。如果它等于 0,则根据
&nbsp;&nbsp;// bitsperpixel 计算颜色数。
&nbsp;&nbsp;int nNumColors = 0;
&nbsp;&nbsp;if (nclrused > 0)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;nNumColors = nclrused;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;else
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;nNumColors = (1&0xff)<<nbitcount;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;System.out.println("The number of Colors is"+nNumColors);

&nbsp;&nbsp;// 某些位图不计算 sizeimage 域,请找出
&nbsp;&nbsp;// 这些情况并对它们进行修正。
&nbsp;&nbsp;if (nsizeimage == 0)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;nsizeimage = ((((nwidth*nbitcount)+31) & ~31 ) >> 3);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;nsizeimage *= nheight;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("nsizeimage (backup) is"+nsizeimage);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;// 读取调色板颜色。
&nbsp;&nbsp;int npalette[] = new int [nNumColors];
&nbsp;&nbsp;byte bpalette[] = new byte [nNumColors*4];
&nbsp;&nbsp;fs.read (bpalette, 0, nNumColors*4);
&nbsp;&nbsp;int nindex8 = 0;
&nbsp;&nbsp;for (int n = 0; n < nNumColors; n++)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;npalette[n] = (255&0xff)<<24
&nbsp;&nbsp;&nbsp;| (((int)bpalette[nindex8+2]&0xff)<<16)
&nbsp;&nbsp;&nbsp;| (((int)bpalette[nindex8+1]&0xff)<<8)
&nbsp;&nbsp;&nbsp;| (int)bpalette[nindex8]&0xff;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// System.out.println ("Palette Color "+n
&nbsp;&nbsp;&nbsp;+" is:"+npalette[n]+" (res,R,G,B)= ("
&nbsp;&nbsp;&nbsp;+((int)(bpalette[nindex8+3]) & 0xff)+","
&nbsp;&nbsp;&nbsp;+((int)(bpalette[nindex8+2]) & 0xff)+","
&nbsp;&nbsp;&nbsp;+((int)bpalette[nindex8+1]&0xff)+","
&nbsp;&nbsp;&nbsp;+((int)bpalette[nindex8]&0xff)+")");
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;nindex8 += 4;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;// 读取图像数据(实际上是调色板的索引)
&nbsp;&nbsp;// 扫描行仍被补足到 4 个字节。
&nbsp;&nbsp;int npad8 = (nsizeimage / nheight) - nwidth;
&nbsp;&nbsp;System.out.println("nPad is:"+npad8);

&nbsp;&nbsp;int ndata8[] = new int [nwidth*nheight];
&nbsp;&nbsp;byte bdata[] = new byte [(nwidth+npad8)*nheight];
&nbsp;&nbsp;fs.read (bdata, 0, (nwidth+npad8)*nheight);
&nbsp;&nbsp;nindex8 = 0;
&nbsp;&nbsp;for (int j8 = 0; j8 < nheight; j8++)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for (int i8 = 0; i8 < nwidth; i8++)
&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;ndata8 [nwidth*(nheight-j8-1)+i8] =
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;npalette [((int)bdata[nindex8]&0xff)];
&nbsp;&nbsp;&nbsp;nindex8++;
&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;nindex8 += npad8;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;image = createImage
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;( new MemoryImageSource (nwidth, nheight,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ndata8, 0, nwidth));
&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else
&nbsp;&nbsp;{
&nbsp;&nbsp;System.out.println ("Not a 24-bit or 8-bit Windows Bitmap, aborting...");
&nbsp;&nbsp;image = (Image)null;
&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fs.close();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return image;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;catch (Exception e)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("Caught exception in loadbitmap!");
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;return (Image) null;
&nbsp;}
您已掌握了读取位图文件的技巧。很容易对此方法进行扩展,使它能够读取单色和 16 色(4 位)格式。
 
  
Java 技巧 43:如何在 Java 应用程序中读取 8 位和 24 位 Microsoft Windows 位图
在 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)<<24) 
  | (((int)bf[4]&0xff)<<16)
  | (((int)bf[3]&0xff)<<8)
  | (int)bf[2]&0xff;
     System.out.println("File type is :"+(char)bf[0]+(char)bf[1]);
     System.out.println("Size of file is :"+nsize);

     int nbisize = (((int)bi[3]&0xff)<<24)
  | (((int)bi[2]&0xff)<<16)
  | (((int)bi[1]&0xff)<<8)
  | (int)bi[0]&0xff;
     System.out.println("Size of bitmapinfoheader is :"+nbisize);

     int nwidth = (((int)bi[7]&0xff)<<24)
  | (((int)bi[6]&0xff)<<16)
  | (((int)bi[5]&0xff)<<8)
  | (int)bi[4]&0xff;
     System.out.println("Width is :"+nwidth);

     int nheight = (((int)bi[11]&0xff)<<24)
  | (((int)bi[10]&0xff)<<16)
  | (((int)bi[9]&0xff)<<8)
  | (int)bi[8]&0xff;
     System.out.println("Height is :"+nheight);

     int nplanes = (((int)bi[13]&0xff)<<8) | (int)bi[12]&0xff;
     System.out.println("Planes is :"+nplanes);

     int nbitcount = (((int)bi[15]&0xff)<<8) | (int)bi[14]&0xff;
     System.out.println("BitCount is :"+nbitcount);

     // 查找表明压缩的非零值
     int ncompression = (((int)bi[19])<<24)
  | (((int)bi[18])<<16)
  | (((int)bi[17])<<8)
  | (int)bi[16];
     System.out.println("Compression is :"+ncompression);

     int nsizeimage = (((int)bi[23]&0xff)<<24)
  | (((int)bi[22]&0xff)<<16)
  | (((int)bi[21]&0xff)<<8)
  | (int)bi[20]&0xff;
     System.out.println("SizeImage is :"+nsizeimage);

     int nxpm = (((int)bi[27]&0xff)<<24)
  | (((int)bi[26]&0xff)<<16)
  | (((int)bi[25]&0xff)<<8)
  | (int)bi[24]&0xff;
     System.out.println("X-Pixels per meter is :"+nxpm);

     int nypm = (((int)bi[31]&0xff)<<24)
  | (((int)bi[30]&0xff)<<16)
  | (((int)bi[29]&0xff)<<8)
  | (int)bi[28]&0xff;
     System.out.println("Y-Pixels per meter is :"+nypm);

     int nclrused = (((int)bi[35]&0xff)<<24)
  | (((int)bi[34]&0xff)<<16)
  | (((int)bi[33]&0xff)<<8)
  | (int)bi[32]&0xff;
     System.out.println("Colors used are :"+nclrused);

     int nclrimp = (((int)bi[39]&0xff)<<24)
  | (((int)bi[38]&0xff)<<16)
  | (((int)bi[37]&0xff)<<8)
  | (int)bi[36]&0xff;
     System.out.println("Colors important are :"+nclrimp);

     if (nbitcount==24)
  {
  // 24 位格式不包含调色板数据,但扫描行被补足到
  // 4 个字节。
  int npad = (nsizeimage / nheight) - nwidth * 3;
  int ndata[] = new int [nheight * nwidth];
  byte brgb[] = new byte [( nwidth + npad) * 3 * nheight];
  fs.read (brgb, 0, (nwidth + npad) * 3 * nheight);
  int nindex = 0;
  for (int j = 0; j < nheight; j++)
      {
      for (int i = 0; i < nwidth; i++)
   {
   ndata [nwidth * (nheight - j - 1) + i] =
       (255&0xff)<<24
       | (((int)brgb[nindex+2]&0xff)<<16)
       | (((int)brgb[nindex+1]&0xff)<<8)
       | (int)brgb[nindex]&0xff;
   // System.out.println("Encoded Color at ("
       +i+","+j+")is:"+nrgb+" (R,G,B)= ("
       +((int)(brgb[2]) & 0xff)+","
       +((int)brgb[1]&0xff)+","
       +((int)brgb[0]&0xff)+")");
   nindex += 3;
   }
      nindex += npad;
      }

  image = createImage
      ( new MemoryImageSource (nwidth, nheight,
          ndata, 0, nwidth));
  }
     else if (nbitcount == 8)
  {
  // 必须确定颜色数。如果 clrsused 参数大于 0,
  // 则颜色数由它决定。如果它等于 0,则根据
  // bitsperpixel 计算颜色数。
  int nNumColors = 0;
  if (nclrused > 0)
      {
      nNumColors = nclrused;
      }
  else
      {
      nNumColors = (1&0xff)<<nbitcount;
      }
  System.out.println("The number of Colors is"+nNumColors);

  // 某些位图不计算 sizeimage 域,请找出
  // 这些情况并对它们进行修正。
  if (nsizeimage == 0)
      {
      nsizeimage = ((((nwidth*nbitcount)+31) & ~31 ) >> 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 < nNumColors; n++)
      {
      npalette[n] = (255&0xff)<<24
   | (((int)bpalette[nindex8+2]&0xff)<<16)
   | (((int)bpalette[nindex8+1]&0xff)<<8)
   | (int)bpalette[nindex8]&0xff;
      // System.out.println ("Palette Color "+n
   +" is:"+npalette[n]+" (res,R,G,B)= ("
   +((int)(bpalette[nindex8+3]) & 0xff)+","
   +((int)(bpalette[nindex8+2]) & 0xff)+","
   +((int)bpalette[nindex8+1]&0xff)+","
   +((int)bpalette[nindex8]&0xff)+")");
      nindex8 += 4;
      }

  // 读取图像数据(实际上是调色板的索引)
  // 扫描行仍被补足到 4 个字节。
  int npad8 = (nsizeimage / nheight) - nwidth;
  System.out.println("nPad is:"+npad8);

  int ndata8[] = new int [nwidth*nheight];
  byte bdata[] = new byte [(nwidth+npad8)*nheight];
  fs.read (bdata, 0, (nwidth+npad8)*nheight);
  nindex8 = 0;
  for (int j8 = 0; j8 < nheight; j8++)
      {
      for (int i8 = 0; i8 < nwidth; i8++)
   {
   ndata8 [nwidth*(nheight-j8-1)+i8] =
       npalette [((int)bdata[nindex8]&0xff)];
   nindex8++;
   }
      nindex8 += npad8;
      }

  image = createImage
      ( new MemoryImageSource (nwidth, nheight,
          ndata8, 0, nwidth));
  }
     else
  {
  System.out.println ("Not a 24-bit or 8-bit Windows Bitmap, aborting...");
  image = (Image)null;
  }

     fs.close();
     return image;
     }
 catch (Exception e)
     {
     System.out.println("Caught exception in loadbitmap!");
     }
 return (Image) null;
 }


您已掌握了读取位图文件的技巧。很容易对此方法进行扩展,使它能够读取单色和 16 色(4 位)格式。 

作者简介
Jeff West 是加州圣地亚哥市的一名工程学研究生。在研究燃烧和火焰扩张的闲暇之余,他沉迷于 Java。  

 
前Facebook资深员工王淮给技术创业团队的十点建议 微软发布Windows Embedded 8系列操作系统 Google Play 4.0抢先体验 中国 vs. 非洲:移动医疗的前世今生 Java大数据框架初创企业Concurrent获400万美元融资 基于Edge Animate开发CSS3 Animations 后端服务商Firebase发布全新iOS SDK [爆料]百度云或在秘密打造实时移动Web App开发框架 打造最佳开发团队的几点建议 Facebook与开发者交恶 扼杀第三方应用 负载大逃亡:四十二路怪兽联军及七条逃生法则 那些年,MIT技术男们奇妙的黑客作品 深度分析:腾讯3.3亿美元收购Epic股份值吗? 传下一代iOS或将推行扁平化设计 iOS开发者注意:苹果将拒绝访问UDID的应用上架 领先Google、Amazon、Dropbox,Apple云存储用户最多 传IBM重新设计晶体管 预计五至七年内成熟 快讯:云计算大会6月召开 云计算概念企业股票飙升 集成开发环境:Qt Creator 2.7.0发布 移动周报:“今日头条”CEO,爱冒险的技术宅 从China Daily的iPad版,看中国纸媒如何摆脱“旧情结” 天睿推出大数据探索平台:“开箱即用”的数据分析 Basho开源Riak CS,与AWS S3兼容的云存储架构 MongoDB Days北京杂记 VMware携手亿阳信通 铺垫混合服务 行业应用,移动优先:移动难七大痛点剖析 HTML5开发必备:游戏开发资源合集 老而弥坚:65岁传奇Android工程师谈开发 2013中国云计算有奖大调查,每周大奖等你拿! Google Reader之死另一个不为人知的原因 小团队谈推广:豆果、金山、微博易、面包旅行 请问FLASH4能做渐变吗?就是颜色由亮到暗或由暗到亮的那种. 日语环境下字符的问题 cookie的问题(最后50’出血 放送) 请大家帮忙改写个代码!!! 哪位朋友帮我看看为什么我在窗体上画不出BREZIER曲线? 不知道access数据库可否做购物处理?具体请来这里。 如何能让sql语句中的表名,字段名等大小写不敏感!! PB连接ORCLE,运行出错。 指针的问题,大家给看看 本人是初学者,请问一个简单的问题 目的没达到,再问,关于span 客户端用ADO连MSSQL,远端的数据库改了数据库端口1433,原先好用的东西就不能用了,不知道改如何解决了 编译出错,是不是就是我的解题思路是错的?? 在vc中能不能建消息队列?怎样建? 用checklistbox如何一次删除所选中的全部项 我做了一个动态生成可上传多个文件的,但是有个问题就是我该如何读取那些字段的值。如:图片标题,我删除一些行后我如何确定新的字段值, 救命!如何用 cable modem 上宽带网 在VC里如何实现QQ的界面啊,急急急急急急急急急急急? web如何实现连接点的回调功能? 新闻系统建模? 如何去掉release版exe文件中export的___CppdebugHook? 用标准C++开发的时候最常用的工具是什么? 到哪里能载到一些编游戏用的2D、3D图象文件啊? 招聘asp.net工程師(深圳) windows关机的问题,把我搞得好惨 请问高手如何判断保存上传图片的字段是否有数据?谢谢! 急!告急了。 学Java与Vc哪个更有实力,更有前途? 有关J2EE部署文件? 请问谁有《微型计算机原理与汇编》潘峰著,电子工业出版社的!!谢谢 一个简单的问题(VFP中) 请问OnKeyPress 和 OnKeyDown 这两个事件有什么区别? 哪里有可视化的jCheckTree组件? 关于译码器的问题,急!! *******在red hat linux下怎么设置DNS?网络设置里没有嘛 help 一个简单的问题 怎样删除干净OCX控件? 我用QQ的自定义查找输入一个QQ号码,但现在忘了我输入的是哪个号码,能不能找回? 框架制作!! 框架的问题 提个弱问! 使用treeview控件,我想给它们的节点图标都换一下,可它默认图标都在上面,怎么去掉默认的。 有牛人吗?准考证英文怎么说? 请大家帮我看看,我的机器是怎么回事?我的机器很不稳定!!! 我为大家共享的资源.找我的人太多了,我吃不消.在这里列BILL.大家看看,书不算太多。 很傻的问题,在线等 ★★如何实现按一下按钮可以终止一个正在运行中的循环?请举个例子,谢谢! 谁能帮我提供一点资料或文档! 告急?(在线等待) 用正则表达式,怎么验证日期(yyyy-mm-dd)的输入啊? 有个英文单词:读音为”杰弃“但我具体忘了是什么单词?有相近的统统发上来, variety和quatity的用法区别(1/2)a variety of .varieties of和a quatity of .quatities of接复数名词时,谓语(2/2)动词单复数的区别 这几个词的复数形式 【【收集】】英语收集,求带有元音【i:】发音的单词【求大神解答】要求:50个,若没有也请说几个,一个小时在线等待, various varied variety用法上的区别 《夏日绝句》诗中哪两句是李清照的人生观,是她在国家危亡之际发出的慨叹 I am ( ).A.an English B.English C.English boy 如何巧妙的记忆variation 和 variety有没有什么联想法或谐音法来记? 夏日绝句中表现人生价值的诗句是哪句 People say that Shen Nong discovered tea.变被动语态 请问variance 与 variation 的区别,在用法上? 夏日绝句其中最能表现李清照志向的语句是 People say that there is a strange creature in the Himalayas.改成被动语态 I have been looking for a man. 英语单词the的所有用法和虚拟语气的构成方式 天空没有留下鸟的痕迹 表现了怎样的感情?难过的时候说这句话是什么意思如果加上下一句"但我已飞过"表达的意思有没有变化呢还有就是整首诗原文 请问五星红旗的红色和黄色的RGB值各是多少,那青天白日满地红旗中的蓝色和红色值又各是多少? 就是那个英语单词the的用法 兔子的英语单词是怎么发音的拜托各位大神 金色、白色、银色、金黄色、紫色的RGB值各是多少? 改错:she sister is a student if引导的从句中为什么some要改成any?还有谁解释下There are only a few,if any. 世说新语德行32 My sister is_student.she studies at_college.填a,an,the,/ if引导的条件状语从句用some还是用any?两本书讲得都不一样,我快弄糊涂了.如If you have____(some,any)questions,I will help you. 世说新语 德行第三八 My sister is a student.She s( ) in Guangming school. 1937年8月28日作文 用sister,is,my,cute,old组成一句话.用上面的几个单词组成一句话. One day an old man is selling a big elephant .A young manOne day an old man is selling a big elephant.A young man comes to the elephant and begins to look at it slowly.The old man goes up to him and says in his ear,“ Don’t say anything about the 做判断划线部分读音是否相同怎么做方法 I'm fourteen,my sister is sixteen.So I'm( ) her.A as old as B not younger than C not so young as D two years yonger thanI was surprised that she could run ( )I could.A as faster as Bso fast than C as fast as Dso fast as a young man put an ad in most of the newspaper是什么意思 区分英语单词划线部分读音,写出有几种读音 这种题的做题技巧例子:1.A.yet B.yes C.cry D.silly (Y划横线)写出这道题的Y有几种读音并讲讲做这种题的技巧 民国时期的报纸字体 是什么字体 Who's ——(careful) Tom Jim or Kate?用括号里单词的正确形式填空,Who's ——(careful) Tom Jim or Kate?用括号里单词的正确形式填空, I'll share a story with you this class,one ____ music can touch one's soul and change one's life.A.thatB.whenC.whichD.where这道题标答是D,但是为什么呢? as a resulf 和as a result of 编英语报纸用什么字体?有没有人出国英语报纸,不知道英语报纸正文都用什么字体和几号字体? 有人帮我读英语吗录音给我She is a student who major in computer network in guilin landscape professional college .she had received a computer class certificate and putonghua certificate.The lessons she had learned are PS,webpage making and "欢迎观看我的相册"英语怎么说?请把正确的写给我,要标准的.要不我不知选哪个?要投票啊观看也可以用进入 谁能告诉我 一张报纸大约有多少个字啊 谢谢 英语翻译(我还在意你,) The boy witnessed___the young man enter the building.A.having seen B.to haveing seen C.to have seen D.seen包括句子的分析什么的,感觉很混乱……已经有一个witness见证了 为什么还会有一个see? They saw the sun (升起)in the east every morning 在宾语从句中,为什么if 后用any,而不用some? The two young men begin to run ____ the building when they see a policeman 报纸标题字体是什么什么请问下标题母爱这行的是什么字体?急 你这样我会很担心的你知道吗 用英语翻译 The girl with short hair looks like her father .(对划线部分提问)划线部分with short hair 报纸上的字为什么会印在桌子上 英语翻译 jenny is a girl with short .blonde hair.为什么填with 要非常明亮黄色的RGB 请问the active young man has to continue his new journey in no time 里的has to做什么用?the active young man has to continue his new journey in no time in stead of stopping to take a rest.原句翻译是:年轻人没有停下来休息,而 what happened to the girl with short hair?是什么意思?英文怎样回答? lucy is twelve.kate is ten.(合并为一句)lucy is two___ ___ ___kate. 天空不留下鸟的痕迹,但我已飞过. 请问variation和variety的辨析?这是高二的单词~ Here's a letter_____an English friend.A.for B.to C.of 应该选哪个,为什么?
备案号:鲁ICP备13029499号-2 说三道四 www.s3d4.cn 说三道四技术文摘