zoukankan      html  css  js  c++  java
  • java解析bmp文件

    最近想做一个图片查看器,因为bmp的图片简单些,也就从这个入手。

             运用的基本知识还是IO的,关键是在于对于“协议”的理解。

             一直觉得这些个协议是个很帅气的东西。感觉就像密码一样,你读到了一个文件,你只有知道对方的“加密”方式,你才能正确的解读,否则你拿着也没用。就像你无法用记事本正确地打开一张图片一样,里面只会全是乱码。

            言归正传,根据以上的说法,我们首先应该去了解的是BMP文件时如何写的。

            BMP文件分为四个部分:文件头信息块,图像描述信息块,颜色表,图像信息区。

            文件头信息块

            这个部分主要是一些基本的信息,比如,开头两个字节最终读出来是BM,是标识BMP文件的,所以如果以后想要读多种文件分类,可以用开头的标识来分类。

            因为此部分的信息后面读取图片意义不大,所以直接读出来,跳过。

            

    Java代码 复制代码 收藏代码
    1.  //读取前面14个字节  
    2. int bflen=14;  
    3. byte bf[]=new byte[bflen];  
    4. dis.read(bf);  

           图像描述信息块

           此部分包含图像的一些基本信息,包括图像大小,宽,高,压缩方式等等。

           宽高是一个非常重要的数据,因此在此我们要获取到宽和高。

           

    Java代码 复制代码 收藏代码
    1. //读取后面40个字节,并且获取到图像的宽和高  
    2. int bilen=40;  
    3. byte bi[]=new byte[bilen];  
    4. dis.read(bi,0,bilen);  
    5. image_width=ChangeInt(bi,7);  
    6. image_height=ChangeInt(bi,11);  

           

    Java代码 复制代码 收藏代码
    1.       /** 
    2.  * byte转变为int数据的方法 
    3.  * @param bi传入的数组 
    4.  * @param end四个byte型数的最后的一个 
    5.  * @return 
    6.  */  
    7. public int ChangeInt(byte[] bi,int end){  
    8.     return(((int)bi[end]&0xff)<<24)  
    9.     |(((int)bi[end-1]&0xff)<<16)  
    10.     |(((int)bi[end-2]&0xff)<<8)  
    11.     |(int)bi[end-3]&0xff;  
    12. }  

             颜色表

             此区域大小由颜色模式而定,在后面读取中基本不怎么用到,所以在此就不详解了。

            图像数据区

            BMP格式的图像分为2色图,16色图,256色图以及真彩图。

            除了真彩色以外,其它三种形式均要用00补齐行字节数,使之成为4的整数倍。

            也因此,我们在处理图像的时候,要注意这个问题,跳过是用来补齐4的整数倍的数据。

            

    Java代码 复制代码 收藏代码
    1. /** 
    2.  * 显示颜色的方法 
    3.  * 对颜色的处理 
    4.  * @param dis数据流 
    5.  */  
    6. public void showRGB24(DataInputStream dis){  
    7.     if(!(image_width*3%4==0)){  
    8.         skip_width=4-image_width*3%4;  
    9.     }  
    10.     //申请数组空间  
    11.     imageG=new int[image_height][image_width];  
    12.     imageB=new int[image_height][image_width];  
    13.     imageR=new int[image_height][image_width];  
    14.       
    15.     for(int h=image_height-1;h>=0;h--){  
    16.         for(int w=0;w<image_width;w++){  
    17.             try {  
    18.                 int blue= dis.read();  
    19.                 int green=dis.read();  
    20.                 int red=dis.read();  
    21.                   
    22.                 imageB[h][w]=blue;  
    23.                 imageG[h][w]=green;  
    24.                 imageR[h][w]=red;  
    25.   
    26.             } catch (IOException e) {  
    27.                 e.printStackTrace();  
    28.                 System.exit(0);  
    29.             }  
    30.               
    31.             if(w==0){  
    32.                 try {  
    33.                     System.out.println(dis.skipBytes(skip_width));  
    34.                 } catch (IOException e) {  
    35.                     e.printStackTrace();  
    36.                       
    37.                 }  
    38.             }                 
    39.         }  
    40.     }         
    41. }  

           存储好颜色之后,后面再重绘出图片就OK 啦。


    一点小结:

    包括后面要做的通信项目,个人觉得关键仍然是协议。不是一种看看就可以的状态,要深入去了解,包括一些特殊的情况。透过现象看本质吧~

  • 相关阅读:
    02 re模块
    24 内置模块re 正则表达式
    pickle 模块
    json模块
    命名元组
    os模块
    24 内置函数 命名元组(namedtuple) ,os ,sys,序列化,pickle,json
    functools
    ccc 音乐播放
    ccc prefab
  • 原文地址:https://www.cnblogs.com/java20130722/p/3206902.html
Copyright © 2011-2022 走看看