首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 其他教程 > 其他相关 >

BMP格式小结

2012-07-08 
BMP格式总结?????????????????????????????????????????????????????????????????? BMP格式总结??????????

BMP格式总结

?????????????????????????????????????????????????????????????????? BMP格式总结

?????????? 学完了画图板的文件保存,也才明白,这个文件的格式只是我们自己定义的,而按照我们的方式保存的图片用我们常用的图片查看器是打不开的,,因为图片查看器所采用的保存格式是另外一种,所以在读取数据的时候无法识别,所以为了改善我们画图板的通用性,在此基础上我们试写了BMP的图像文件格式。

????????? ?首先,典型的BMP图像文件由四部分构成:位图文件头,文图信息头,颜色表和位图数据;其中文件头主要包括BMP图像文件的类型,文件大小和位图起始位置等信息;信息头数据主要用于说明位图的尺寸等信息;而颜色表则是说明位图中的颜色,不过24位图没有颜色表;最后位图数据中记录了位图的每一个像素值。

???????? ?当我们需要打开一个BMP24位的图像文件时,就要读取图片的基本信息及数据:

// 读取图片宽度与高度int len = 54;// 定义一个数组 来存放读取到的字节byte bd[] = new byte[len];dis.read(bd, 0, len);int  width = ChangeInt(bd, 21);int  height = ChangeInt(bd, 25);// 将宽度和高度存入数组中DrawListener.area = new int[height][width];int skipLen=0;// 按行读取(从下往上,从左往右)if (width * 3 % 4 != 0) {skipLen = 4-width * 3 % 4;}//(从下往上,从左往右)for (int i=height-1;i >=0;i--) {for (int j=0;j<width;j++) {// 读取三原色int blue=dis.read();int green=dis.read();int red=dis.read();if(j==width-1){dis.skip(skipLen);}                              // 将三原色转换为颜色Color color=new Color(red, green, blue);// 将相对应的颜色转为整形存入数组中(下标极为重要)DrawListener.area[i][j] = color.getRGB();}}draw.repaint();// 调用重绘的方法

?????????? 这里我一开始做的不太完整,关键就在于是否需要跳0,,因为Windows规定一个扫描行所占的字节行数必须是4的倍数,可是一个像素由三个字节组成,所以不足的就补0了,可是在读取的时候要把补的0给跳过,否则显示出来的BMP图片是倾斜的,所以要把补的0给跳过,而且每一行都要跳。最后在重绘的时候,可以自己再写一个方法去显示图片,也可以调用画布的再重绘的方法。

?????????? 当把用我们的画板绘制的图片保存为BMP24位的格式的时候,只需要用别人定义好的格式将数据写入内存,同样的,要写文件的头文件,信息头,颜色表及图像数据区;但要注意的是因为我们写入的数据都是int,所以要通过自己定义的方法将其转换为byte:

  private byte[] ChangeByte(int a) {byte b4=(byte) ((a) >> 24);byte b3=(byte) ((a) >> 16);byte b2=(byte) ((a) >> 8);byte b1=(byte) ((a)) ;byte[] bytes={b1,b2,b3,b4};return bytes;}

?

????????? ?至此,才终于可以将画板的文件保存为BMP,而且画板也可以打开BMP的文件,可是到这里,我的画板打不开他自己画的图片,却可以打开系统BMP图片,而画板画的图片却可以通过图片查看器来浏览,这让我们感到无比的神奇,几经周折,才发现最大的问题不是出在BMP的格式上,而是在将byte的数据转换为int时,写错了括号搞错了优先级(必须先进行与运算再移位),我也才明白之前能打开系统BMP图片只是刚好碰运气而已。唉,这让我更加发现,写代码绝对是个细活。。。。

private  int ChangeInt(byte[] b, int start) {// 必须 先与运算  再移位return (((int) b[start] & 0xff) <<24)        | (((int) b[start - 1] & 0xff) << 16)        | (((int) b[start - 2] & 0xff )<< 8)                         | ((int) b[start - 3]& 0xff);}

???????

热点排行