有了IO流的基础之后,就可以写一些简单的关于BMP文件的操作程序了。
在实际生活中,我们经常看到或用到BMP格式的图片,那么,到底什么是BMP文件?
根据百度百科的介绍,BMP是一种与硬件设备无关的图像文件格式,使用非常广。它采用位映射存储格式,除了图像深度可选以外,不采用其他任何压缩,因此,BMP文件所占用的空间很大。BMP文件的图像深度可选lbit、4bit、8bit及24bit。BMP文件存储数据时,图像的扫描方式是按从左到右、从下到上的顺序。 由于BMP文件格式是Windows环境中交换与图有关的数据的一种标准,因此在Windows环境中运行的图形图像软件都支持BMP图像格式。
意思是说,BMP是一种通用型的图形图像文件保存格式。它的保存和读取时与硬件无关的,在任何操作系统中BMP的文件保存方式和格式都是相同的,真正做到了“跨平台”,所以BMP是一种用途很广的图像保存方式。window自带的画板就是画的BMP格式图片(当然,你可以将之转为别的图像格式)。
那么怎么保存和读取图片文件呢?
做过简单画板程序或者自定义图像保存读取的人都知道,我们要保存和读取一幅图(通常是我们自己画的),实际上保存的都是图像中的点。比如,我们用了Graphics g.fillLine(x1,y1,x2,y2);在画板上画了一条直线,那么我们只需要保存直线的2个端点(x1,y1)和(x2,y2)就行了。读取的时候,也是读取这二个点(也就是让程序知道这二个点),然后调用Graphics g.fillLine(x1,y1,x2,y2);来画这条直线就行了。
这就是保存和读取图片(不管是你自己的程序画的,还是别人的程序画的或者就是照片)的重点:怎样保存,就怎样读取。
但这样出现了一个问题,在一般的图片(比如照片)中是很少有那些规则的图形的,那么我们保存什么?很容易想到的是,我们可以保存图片上的点,而事实上BMP也是如此。
BMP文件时怎样保存的呢?
典型的BMP图像文件由四部分组成:
1:位图文件头数据结构,它包含BMP图像文件的类型、显示内容等信息;
2:位图信息数据结构,它包含有BMP图像的宽、高、压缩方法,以及定义颜色等信息;
3:调色板,这个部分是可选的,有些位图需要调色板,有些位图,比如真彩色图(24位的BMP)就不需要调色板;
4:位图数据,这部分的内容根据BMP位图使用的位数不同而不同,在24位图中直接使用RGB,而其他的小于24位的使用调色板中颜色索引值。
具体的数据类型和保存的单位可以自己上网查。
在简单的读取中,我们只需要知道BMP文件的宽度和高度、调色板(不设置就是24色,也就是说调色板都不需要用到,我就没用到)、位图数据(即每个点的颜色)即可。PS:我们甚至不用仔细到单个点的位置,因为图像是按规律储存的,我们也是按规律读取和重绘的。大家可以看我的代码。
还有一点,因为BMP是不失真保存,即一个点一个点的读取与重绘,注定会比较慢。
想提高读取重绘的速度,可以考虑用双缓冲(double_buffer)或多线程来绘制。如果您有更好的提高速度的方法,你可以给我留言,一起交流学习。
还有一点,用多线程的时候,因为多个线程是用同一画笔,即同一个Graphics来画的,会出现问题,我觉得我的解决方法是比较简单的(这也是我比较自豪的地方,哦也),大家可以看看我的代码