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

关于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文件格式分析 #### 一、BMP文件概述 BMP文件格式,全称Bitmap或者Device-Independent Bitmap (DIB),是一种常见的图像文件格式,在Windows操作系统中被广泛应用。其特点是能够无损地保存图像像素数据,使得...

    bmp文件格式分析分析

    ### BMP文件格式详解 #### 一、概述 BMP(Bitmap File)是一种常见的图像文件格式,由Microsoft设计,广泛应用于Windows...未来随着技术的发展,BMP格式可能会继续演进,但其基本原理和结构仍然具有重要的参考价值。

    bmp格式分析及格式转换

    本篇将深入探讨BMP格式的特性,以及如何进行BMP格式的分析与转换。 首先,BMP文件的结构分为文件头和位图信息头两部分。文件头(BITMAPFILEHEADER)包含了文件的基本信息,如文件类型标识、文件大小、保留字段和...

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

    【BMP图像文件格式分析与显示】 BMP(Bitmap)是一种常见的位图图像文件格式,尤其在Windows系统中广泛使用。本次实验旨在深入理解BMP文件的结构,并掌握如何从文件中读取图像数据并显示出来。以下是关于BMP文件...

    BMP文件格式分析学习

    了解BMP文件格式对于进行图像处理、编程或分析图像文件非常重要。通过解析这些头部信息,我们可以读取和创建BMP图像,同时理解不同颜色深度如何影响图像质量和存储需求。在开发图形软件或者进行图像分析时,掌握这些...

    BMP格式分析.mht

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

    GIS 数据 bmp格式 海水分布图

    在本压缩包中,我们关注的是“GIS数据”、“bmp格式”以及“海水分布图”这三个核心概念。 首先,GIS数据是GIS系统中的基础,它包含了关于地球表面特征的各种信息,如地形、人口分布、交通网络等。这些数据通常以点...

    BMP格式图片的生成

    在本文中,我们将深入探讨如何生成BMP格式的图片,并基于描述中的代码进行分析。 首先,我们需要了解BMP文件的基本结构。一个BMP文件由以下几个部分组成: 1. 文件头(File Header):这是文件的起始部分,包含...

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

    【图像处理bmp格式分析及显示】的详细知识点: 1. **设备无关位图(DIB)**:DIB 是 BMP 文件的一种格式,它不依赖于特定的硬件设备,因此具有良好的兼容性和通用性。DIB 文件包含了颜色信息,使得它们在不同设备上...

    BMP文件分析及用python读取

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

    BMP图像文件格式分析

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

    BMP 格式详解。对于想了解BMP格式很有用。

    BMP(Bitmap)格式是一种常见的图像文件格式,广泛应用于Windows操作系统和许多其他软件中。它是一种未经压缩的、逐...无论是进行图像分析、开发图形软件还是进行系统级编程,掌握BMP格式的相关知识都是不可或缺的。

    bmp格式图片转换为raw格式

    BMP格式图片包含图像的元数据,如宽度(Width,W)、高度(Height,H)、颜色深度等,以及实际像素数据。RAW格式则更接近于相机传感器的数据,通常包含每个像素的红、绿、蓝分量,没有预处理或色彩空间转换。 要...

    DEM输出为BMP格式图片

    标题中的“DEM输出为BMP格式图片”是指将数字高程模型(Digital Elevation Model,简称DEM)数据转换成位图图像(Bitmap,通常表示为BMP)的过程。这一过程通常涉及地理信息系统(Geographic Information System,...

    BMP格式指纹处理程序

    BMP格式的指纹处理程序是一种用于处理和分析指纹图像的软件工具。在计算机视觉和生物识别技术领域,指纹识别是常用的身份验证方法,因为每个人的指纹都是独一无二的。本程序使用C++作为高级编程语言,并利用C语言...

    raw格式转换为bmp格式(包括代码,lena.raw和lena.bmp)

    标题中的"raw格式转换为bmp格式"指的是通过编程实现这一转换过程。在这个项目中,使用了C++语言编写了一个名为`raw2bmp.cpp`的程序,该程序可以读取RAW格式的图像数据,并将其转化为BMP文件。C++是一种强大的系统级...

    春鹏图片格式分析器

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

    bmp格式转rle

    BMP格式是一种无损的、未压缩的位图格式,通常用于存储高质量的图像,而RLE则是一种简单且有效的压缩算法,常用于减少图像文件的大小,尤其适用于具有大量重复像素的图像。 在Android系统中,由于内存和存储空间的...

    三分钟解析24位真彩BMP格式文件

    **三分钟解析24位真彩BMP格式文件** BMP(Bitmap)是Windows操作系统中最常见的位图图像格式,它不包含任何压缩,因此文件体积较大,但图像质量...通过解压并分析这些文件,可以更深入地理解和掌握BMP格式的工作原理。

Global site tag (gtag.js) - Google Analytics