BMP是Window操作系统中的标准图像文件格式,使用非常广。它采用位映射存储格式,除了图像深度可选以外,不采用其他任何压缩,因此,BMP文件所占用的空间很大。BMP文件的图像深度可选lbit、4bit、8bit及24bit。BMP文件存储数据时,图像的扫描方式是按从左到右、从下到上的顺序。由于BMP文件格式是Windows环境中交换与图有关的数据的一种标准,因此在Windows环境中运行的图形图像软件都支持BMP图像格式。
典型的BMP图像文件由四部分组成:
1:位图头文件数据结构,它包含BMP图像文件的类型、显示内容等信息;(14字节)
2:位图信息数据结构,它包含有BMP图像的宽、高、压缩方法,以及定义颜色等信息;(40字节)
3:调色板,这个部分是可选的,有些位图需要调色板,有些位图,比如真彩色图(24位的BMP)就不需要调色板;
4:位图数据,这部分的内容根据BMP位图使用的位数不同而不同,在24位图中直接使用RGB,而其他的小于24位的使用调色板中颜色索引值。
现在就简述一下24位图的读取步骤:
其实读取bmp文件也就是按照他的文件格式与协议,一样样的读出。
第一步,读出BMP文件的前14个字节,此为bmp的头文件
第二步,读bmp文件的接下来40个字节,此为bmp文件的信息头文件,内部包含图片的宽高数据
第三步,读取位图数据,这里还是要说说的,因为读取的是bmp文件,是个图片文件,而图片文件都是由一个个像素组成的,每个像素由三原色的配比构成,所以我们就要构建三个数组,来储存每个原色,这样才能通过数组中三原色的配比构成来读取bmp文件。
这里牵涉到一个很重要的东西,就是补零,windows规定一个扫描行所占的字节数必须是4的倍数,不足的就以0补充,这才强调了补零的重要性,有则跳过,没有就直接读,不然显示的bmp图像会倾斜。
这里还有一个东西是非常重要的,那就是位运算,关于位运算,其实就是通过与和非把byte型转化为int型,下面是代码:
其实所有文件的读取只要按照它们的协议,解析它们的格式,就能通过一些方式化整为零的读取与写出。
典型的BMP图像文件由四部分组成:
1:位图头文件数据结构,它包含BMP图像文件的类型、显示内容等信息;(14字节)
2:位图信息数据结构,它包含有BMP图像的宽、高、压缩方法,以及定义颜色等信息;(40字节)
3:调色板,这个部分是可选的,有些位图需要调色板,有些位图,比如真彩色图(24位的BMP)就不需要调色板;
4:位图数据,这部分的内容根据BMP位图使用的位数不同而不同,在24位图中直接使用RGB,而其他的小于24位的使用调色板中颜色索引值。
现在就简述一下24位图的读取步骤:
其实读取bmp文件也就是按照他的文件格式与协议,一样样的读出。
第一步,读出BMP文件的前14个字节,此为bmp的头文件
int count1=14;
byte [] hbmp=new byte[count1];
dis.read(hbmp);//读到哪里,从哪里读,读多少
第二步,读bmp文件的接下来40个字节,此为bmp文件的信息头文件,内部包含图片的宽高数据
int count2=40;
byte [] ibmp=new byte[count2];
dis.read(ibmp);
image_width=changeInt(ibmp,7);//宽度
image_height=changeInt(ibmp,11);//高度
System.out.println(image_height+" "+image_width);
int nbitcount=(((int)ibmp[15]&0xff)<<8)|(int)ibmp[14]&0xff;//位数
int nsizeimage=changeInt(ibmp,23);//原图大小
第三步,读取位图数据,这里还是要说说的,因为读取的是bmp文件,是个图片文件,而图片文件都是由一个个像素组成的,每个像素由三原色的配比构成,所以我们就要构建三个数组,来储存每个原色,这样才能通过数组中三原色的配比构成来读取bmp文件。
imageR=new int[image_height][image_width];//红色数据
imageG=new int[image_height][image_width];//绿色数据
imageB=new int[image_height][image_width];//蓝色数据
//得到每行的补0数据
if(image_width*3%4!=0){
this.skip_num=4-image_width*3%4;
}
//按行读取,如果H,M为正则倒着来
for(int h=image_height-1;h>=0;h--){
for(int w=0;w<image_width;w++){
//读入三原色
int blue=dis.read();
int green=dis.read();
int red=dis.read();
imageB[h][w]=blue;
imageG[h][w]=green;
imageR[h][w]=red;
// System.out.println(blue+" "+green+" "+red);
}
//补0
for(int i=0;i<this.skip_num;i++){
dis.readByte();
}
}
这里牵涉到一个很重要的东西,就是补零,windows规定一个扫描行所占的字节数必须是4的倍数,不足的就以0补充,这才强调了补零的重要性,有则跳过,没有就直接读,不然显示的bmp图像会倾斜。
这里还有一个东西是非常重要的,那就是位运算,关于位运算,其实就是通过与和非把byte型转化为int型,下面是代码:
public int changeInt(byte [] ibmp,int start){
return (((int)ibmp[start]&0xff)<<24)|(((int)ibmp[start-1]&0xff)<<16)|(((int)ibmp[start-2]&0xff)<<8)|((int)ibmp[start-3]&0xff);
}
其实所有文件的读取只要按照它们的协议,解析它们的格式,就能通过一些方式化整为零的读取与写出。