`
孙瑞鸿
  • 浏览: 16989 次
  • 性别: Icon_minigender_2
社区版块
存档分类
最新评论

bmp文件解析

 
阅读更多
解析bmp图像
        今天做了一个很好玩的东西————bmp图片解析器。刚看到的时候我觉得超难,完全不
懂,做出来之后,觉得其实很简单!接下来就让我来介绍一下吧!
       在真正做解析器之前我们应该先了解一些基础知识!
位运算:
1.由byte型转为int型(下面是4个byte转为一个byte)
  
(((int)b4&0xff)<<24
   |(((int)b3&0xff)<<16)
   |(((int)b2&0xff)<<8)
   |(((int)b1&0xff)<<0));

   如果只是一个byte转一个int只需(((int)b1&0xff)<<0));即可
   我在做这个的时候遇到一个问题:
          在解析系统画板的画或下载的bmp图像时这样写((int)b1&0xff<<0));
   不会出现问题!但是在解析自己画板保存的bmp图像时出现问题!请教大神后,给我的解
   释是对上面这种写法系统是兼容的,但对自己画板的画可能不兼容!所以图像就会乱!大
   家可以参考,如有问题欢迎纠正!
  
/**
	 * 将4个byte数转换成int型
	 * @param b1
	 * @param b2
	 * @param b3
	 * @param b4
	 * @return
	 */
	public int change(byte b1,byte b2,byte b3,byte b4){
		return (((int)b4&0xff)<<24|(((int)b3&0xff)<<16)
		|(((int)b2&0xff)<<8)|(((int)b1&0xff)<<0));
	}	
  
2.由int型转为byte型(将一个int类型的数data转换为byte型存入数组)
        
byte[] b=new byte[4];
	b[0]=(byte) ((data>>>0)&0xff);
	b[1]=(byte)((data>>>8)&0xff);
	b[2]=(byte)((data>>>16)&0xff);
	b[3]=(byte)((data>>>24)&0xff);

位图的一个像素值所占的字节数:
当biBitCount=1时,8个像素占1个字节;
当biBitCount=4时,2个像素占1个字节;
当biBitCount=8时,1个像素占1个字节;
当biBitCount=24时,1个像素占3个字节; 

现在开始正题
bmp结构: BMP文件由文件头、位图信息头、颜色信息和图形数据四部分组成。
1.文件头信息

   BMP文件头(14字节)BMP文件头数据结构含有
   BMP文件的类型、文件大小和位图起始位置等信息。
文件类型BM——————————————————2个字节(4D42)
文件大小————————————————————4个字节
保留信息————————————————————4个字节
偏移量    ————————————————————4个字节
BmpData bd=new BmpData();
			//文件头信息大小
			int bheadlen=14;
			//创建一个byte数组保存文件头信息
			byte[] bhead=new byte[14];
			//将文件信息读入数组
			dis.read(bhead, 0, bheadlen);
			//调用change将byte转为int
			bd.size=this.change(bhead[2], bhead[3], bhead[4], bhead[5]);
			bd.bfOffBits=this.change(bhead[10], bhead[11], bhead[12], bhead[13]);

2.位图信息(我做的是24真彩色)
位图信息头(40字节)  BMP位图信息头数据用于说明位图的尺寸等信息。
本结构所占用字节数—————————————4个字节
位图的宽 ————————————————————4个字节 (宽和高的顺序不能错)
位图的高 ————————————————————4个字节
   目标设备的级别————————————————2个字节
每个像素所需的位数,必须是1(双色), 4(16色),8(256色)或24(真彩色)之一
              ————————————2个字节
位图压缩类型,必须是0(不压缩)————2个字节
位图的大小  ——————————————————4个字节
位图水平分辨率,每米像素数   ——————4个字节
位图垂直分辨率,每米像素数   ——————4个字节
位图实际使用的颜色表中的颜色数      ——4个字节
位图显示过程中重要的颜色数   ——————4个字节
//位图信息头大小(只取了部分需要的数据)
			int bmesslen = 40;
			byte[] bmess=new byte[bmesslen];
			dis.read(bmess, 0, bmesslen);
			bd.biWidth=this.change(bmess[4], bmess[5], bmess[6], bmess[7]);
			bd.biHigh=this.change(bmess[8], bmess[9], bmess[10], bmess[11]);
			width=bd.biWidth;
			high=bd.biHigh;
3.颜色表
颜色表用于说明位图中的颜色,它有若干个表项,每一个表项是一个RGBQUAD类型的
结构,定义一种颜色。
蓝色的亮度(值范围为0-255)
绿色的亮度(值范围为0-255)
红色的亮度(值范围为0-255)
4.位图数据
位图数据记录了位图的每一个像素值,记录顺序是在扫描行内是从左到右,扫描行之间
是从下到上。
//位图数据大小
			int datalen;
			//判断宽度是不是4的整数倍
			if(width*3%4==0){
				datalen=width*3;
			}else{
				//宽度不是4的整数倍是跳过系统补0后的宽度
				datalen=4-width*3%4+width*3;
			}
			//将数据存入data二维数组中
			byte data[][]=new byte[high][datalen];
			for(int i=0;i<high;i++){
					dis.read(data[i], 0, datalen);
			}
			//将byte类型的data数组转换为int类型
			int data1[][]=new int[high][datalen];
			for(int i=0;i<high;i++){
				for(int j=0;j<datalen;j++){
				//两种方法
				//data1[i][j]=(data[i][j]+256)%256;
				data1[i][j]=((int)data[i][j]&0xff);
				}
如此即可吧一个bmp图像信息读取出来
然后在画板上画出即可
/**
	 * 显示图片,即按照给定的数据画点(从下到上,从左到右)
	 * @param data:给定的图像的数据
	 */
	public void draw( int[][] data){
		int x=300,y=550;
		for(int j=0;j<data.length;j++){
		for(int i=2;i<width*3;i+=3){
	        //读取图像的颜色信息
			int blue=data[j][i-2];
			int green=data[j][i-1];
			int red=data[j][i];
			g.setColor(new Color(red,green,blue));
			g.drawLine(x, y, x, y);
			x++;
			}	
		x=200;
		y--;
		System.out.println(x+","+y);
		}
	}

现在觉得不难了吧!
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics