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);
	}

       

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值