`
MisYou
  • 浏览: 2723 次
最近访客 更多访客>>
文章分类
社区版块
存档分类
最新评论

关于BMP格式的分析

阅读更多
一、其实那些图片不同格式,视频不同格式,文本不同格式、、等都本质上是一样的,都是一个文件,而不同的是你那怎么样的读取规则去读取它,只要读的规则跟存的规则是一样的,就能得到你想要的东西,不同的只是规则而已。   
   bmp格式是一种比较简单的图片存储格式,bmp文件分为四个部分,第一是文件头信息块占14个字节,第二部分是图像描述信息块,占36字节,第三部分是颜色表,占4个字节和但是我们目前用不到,第四部分是图像数据区,那就要看大小了。
二、读取的时候,因为它是按顺序读的,不重不漏,所以我用的是先新建两个byte数组,先把头文件中14+40个字节读取到这两个数组中。而画图时,我们要用到的第二个数组中指定位置的几个字节,但是要用到的应该是int型的,所以要有个方法把4个byte转化为1个int
/**
* 要将一个字节转化为一个int
* @param bb byte数组
* @param lenth 起点位置
* @return 返回的int型数据
*/
public int  changeInt(byte[] bb,int lenth){
int t=(((int)(bb[lenth] & 0xff) << 24) | ((int)(bb[lenth-1] & 0xff) << 16) | ((int)(bb[lenth-2] & 0xff) << | ((int)(bb[lenth-3] & 0xff )<< 0));
return t;
    }
  这个方法就是取特定lenth及前面3个byte,并且把它们按照bb[lenth]、bb[lenth-1]、bb[lenth-2]、bb[lenth-3]的顺序再拼接起来,就得到这个int数的存储顺序。
  三、头文件中我们要用到的就是height、width。接下来就是读取图像数据区了,因为bmp中是每个点按它的R、G、B值存的,而且是从左下角开始一行一行读的。这样我们就可以弄三个二维数组存每个点的R、G、B值,这样我们重绘时就可以把每个点按它的R、G、B值设颜色然后再画就行了。具体读取方法代码如下:
/**
* 获取图像数据

*/

public void readBmp(){
try {

    java.io.FileInputStream fil=new java.io.FileInputStream(s);

    java.io.DataInputStream dat=new java.io.DataInputStream(fil);

    byte[] bb=new byte[headlen];//获取头文件信息

     dat.read(bb, 0, headlen);

    byte[] bb1=new byte[wlen];//获取位图信息

     dat.read(bb1, 0,wlen);

     height=changeInt(bb1,11);//获取高度的值

      width=changeInt(bb1,7);//获取宽度的值

/**

* 读取图像数据,并存到三个二维数组中,分别对应RGB

*/

     imageB=new int[height][width];

     imageG=new int[height][width];

     imageR=new int[height][width];

     int skip_width = 0;

     if(width*3%4 != 0){

         skip_width = 4-width*3%4;

     }

    for(int i=height-1;i>=0;i--){

       for(int j=0;j<width;j++){

           int bule =dat.read();

           int green=dat.read();

           int red=dat.read();

           if(j==0)
dat.skipBytes(skip_width);

          imageB[i][j]=bule;

          imageR[i][j]=red;

          imageG[i][j]=green;

          bmp.g.setColor(new Color(imageR[i][j],imageG[i][j],imageB[i][j]));

          bmp.g.drawLine(j+(800-width)/2, i+(800-height)/2, j+(800-width)/2, i+(800-height)/2);

        }

    }

dat.close();

         } catch (Exception ee) {

             ee.printStackTrace();

}
}

四、这里我在菜单中加了一个监听器,监听器是弹出一个文件选择框
    JFileChooser jfs=new JFileChooser();//显示弹出的选择框
jfs.setFileSelectionMode(JFileChooser.FILES_ONLY);
jfs.showOpenDialog(bmp);
file=jfs.getSelectedFile();
s=file.getAbsolutePath();//用s取取得的文件路径名
   用文件选择框就可以打开不同的文件,可以有选择,而且刚好可以把选择的文件名传到上面输入流中。
五、本以为写入和读是一个相反的过程,应该很简单,但是事实却不是这样。首先一点,我们读取的时候考虑到了补0的情况,但是在写的时候要是考虑的话就太麻烦了,所以我们果断选择了大小不用补0的情况。整个思路是先显示界面,然后在界面上加监听器画画,然后是在菜单栏中加动作监听器,得到文件路径后往文件内写数据。
  1、同样,在这里我也选择了在菜单上添加选择框,
JFileChooser jfs=new JFileChooser();//显示弹出的选择框
jfs.showSaveDialog(null);
file=jfs.getSelectedFile();
//判断file是否为空,因为文件存在的话就没有选择了,会报空指针
if(file!=null){
  s=file.getAbsolutePath();//用s取取得的文件路径名
  s=s+".bmp";
  creatFile(s);
}
write(s);
选择文件框和保存框差不多,也是取路径存到S中,但是我在这里很有创造性的在s后面加上了.bmp,这样就保存的时候就自动被系统识别为bmp格式。
2、考虑到后面要读取每个点的R、G、B数值,我就用了一个缓冲图片BufferedImage 在这上面画东西,再画到界面上,同时这个缓冲图片是主类的一个属性,这样我们就可以在动作监听器中也可以用了。
Node1 node1=new Node1();
node1.x=e.getX();
node1.y=e.getY();
node1.count=count;
alist1.add(node1);
g=tt.img.getGraphics();
if(count==0){
g.drawLine(e.getX(), e.getY(),e.getX(), e.getY());
}
          else{
    g.drawLine(lastX, lastY,e.getX(), e.getY());}
    tt.getGraphics().drawImage(tt.img, 0, 0,null);//在界面上画缓冲图片
     lastX = e.getX();
    lastY = e.getY();
    count++;
画点我用的是MouseMotionListener由于我画点的时候用的是数组队列来存的每个点数据,然后把每个点和前面的那个点连接起来,但是第一个点前面没有点,系统默认跟原点连了。所以我在每个点属性中加了一个计数器,这样就解决了这个问题。重绘的时候也是根据这个来画的。
//重绘所划过的图
  public void paint(Graphics g){
  super.paint(g);
//   for(int i=0;i<l.alist.size();i++){
//   g.drawLine(l.alist.get(i).x1, l.alist.get(i).y1, l.alist.get(i).x2, l.alist.get(i).y2);
//   }
  for(int i=0;i<ll.alist1.size();i++){
  if(ll.alist1.get(i).count==0){
  g.drawLine(ll.alist1.get(i).x, ll.alist1.get(i).y, ll.alist1.get(i).x, ll.alist1.get(i).y);
  }else{
  g.drawLine(ll.alist1.get(i-1).x, ll.alist1.get(i-1).y, ll.alist1.get(i).x, ll.alist1.get(i).y);
  }
  }
  }
3、然后整个程序的核心就是这个写入方法。
没有办法,只能一个字节或者几个字节往里写。也有一个把int数据转化为byte数组的方法,跟前面那个基本上是相反的
/**
* 把一个int型变成byte数组
* @return
*/
public byte[] changeByte(int i){
byte[] a = new byte[4];    
a[0] = (byte) (0xff & i);    
a[1] = (byte) ((0xff00 & i) >>;       
a[2] = (byte) ((0xff0000 & i) >> 16);     
a[3] = (byte) ((0xff000000 & i) >> 24);
return a;
}
举个例子,int i=600*600*3(这是我的图像数据大小)
  i转化为2进制是100000111101011000000,这个方法取第一个a[0]是用11111111和i做或运算,这样就是把i除最后面8个位保存了其他就都变成了0,这样就保存了前面8个,也就是11000000 也就是十进制的192 十六进制的co,同理,a[1]是只取到了i从后面数第9到第16位的值,也就是01111010 十进制的122,十六进制的7A,a[2]为 10000 ,十进制的16,十六进制的10,a[3]为0;写入文件的时候也就是C0 7A 10 00.
头文件中其他数也是按照其他图片写入的。
关于那个图像数据,因为我是画到BufferedImage上面的,而BufferedImage中有一个getRGB()方法,返回的是一个int型数,而它只有三个byte存了数据,就是后面三个,所以我们要取到这个三个byte,再分别写入
for(int i=599;i>=0;i--){
     for(int j=0;j<600;j++){
int rgb=tt.img.getRGB(j, i);//这里的int数据保存了三个字节的内容
//移位获取每个点的rgb数值
byte rgbs[]=new byte[3];
rgbs[0]=(byte)rgb;
rgb=rgb>>8;
rgbs[1]=(byte)rgb;
rgb=rgb>>8;
rgbs[2]=(byte)rgb;
ioo.write(rgbs);
rgb=rgb>>8;
     }
}
也就是把每个点的RGB按顺序存进去,这样就基本上把整个文件写好了。我现在保存自己画的图片能被自己写的程序读取,也能被系统读取了!!!!
   总结一点就是,只要知道它的存取规则,也就是协议,理论上什么文件都可以读取写入的。下次可以尝试其他的文件。
分享到:
评论

相关推荐

    bmp格式分析及格式转换

    bmp格式分析及格式转换 支持 16位bmp和8位bmp的转换 24位bmp转灰度

    BMP文件格式分析

    bmp文件头分析,文件数据大小,宽度像素的计算方法。利用winhex底层分析进行bmp文件的重现。

    BMP文件格式分析学习

    BMP文件格式分析-图像学习

    图像处理bmp格式分析及显示

    图像处理bmp格式图片信息头分析以及在MFC上代码实现

    bmp文件格式分析数据

    bmp文件格式分析,bmp文件格式分析bmp文件格式分析bmp文件格式分析bmp文件格式分析bmp文件格式分析bmp文件格式分析bmp文件格式分析bmp文件格式分析

    bmp文件格式分析分析

    HPI是什么意思?_HPI是什么意思?_HPI是什么意思?_HPI是什么意思?_HPI是什么意思?_HPI是什么意思?_HPI是什么意思?_HPI是什么意思?_HPI是什么意思?_

    BMP格式分析.mht

    BMP(Bitmap-File)图形文件是Windows采用的图形文件格式,在Windows环境下运行的所有图象处理软件都支持BMP图象文件格式。Windows系统内部各图像绘制操作都是以BMP为基础的。Windows 3.0以前的BMP图文件格式与显示...

    BMP图像文件格式分析与显示

    对于bmp图像文件格式进行分析与显示的实验报告

    BMP文件分析及用python读取

    一、BMP文件分析 1. 什么是BMP(位图)? 常见的图像文件格式有:BMP、JPG...BMP格式的图片,没有使用任何压缩算法,这种方式在以前使用的比较多,现在用的就比较少了,不过为了学习图像处理算法,所以先以该种格式的文

    bmp文件格式分析及其编程

    bmp文件格式分析及其编程 bmp文件格式分析及其编程

    BMP图像文件格式分析

    多媒体技术中对BMP文件格式进行分析,摘要必须大于50个字节!,

    BMP文件格式分析.pdf

    BMP文件格式分析.pdf

    基于BMP格式图片的指纹对比分析识别系统

    基于bmp图片的指纹对比分析识别系统,核心程序是国外两个学生做的毕业设计,我就拿来直接改了改,基本上实现了256*256灰度指纹图像的识别过程,直方图增强,读表法细化,细节点对比。程序开发环境运行环境vs2008+...

    春鹏图片格式分析器

    利用此软件可以对常用的图片文件格式进行分析。 对于bmp格式,能够分析出文件头、文件...此软件集bmp文件格式分析器、png文件格式分析器、gif文件格式分析器、jpeg/jpg文件格式分析器于一身。是图片格式学习的利器。

    BMP文件格式分析,更深入讲解BMP文件格式的构造

    比较完整的BMP文件格式分析 BMP文件格式分析,更深入讲解BMP文件格式的构造

    BMP格式图片无损压缩成JPG格式图片

    BMP格式图片无损压缩成JPG格式图片,便于光学测试图片分析使用。

    bmp.zip_bmp 分析

    给定若干幅用BMP格式保存的数字图像,编写一个程序读取BMP图像。 用UltraEdit等工具分析保存的BMP图像格式

    简洁的BMP分析器

    简洁的BMP分析工具,适合查看BMP格式的各个参数

Global site tag (gtag.js) - Google Analytics