BMP由四部分组成 ,位图文件头 , 位图信息头 , 颜色 , 图像数据区
BMP图片是三个字节为一个颜色保存,将字节拼接为int需要使用位移来做
位图文件头 (12个字节):
0000-0001:文件标识,为字母ASCII码“BM”,42 4D。
0002-0005:整个文件大小,单位字节。
0006-0009:这个位置的数字是被微软保留的 000A-000D:记录图像数据区的起始位置。从文件开始到位图数据(bitmap data)之间的偏移量。 位图信息头()
000E-0011:图像描述信息块的大小 0012-0015:图像宽度。以像素为单位。 0016-0019:图像高度。以像素为单位。 001A-001B:图像的plane总数(恒为1)。 001C- 001D:记录像素,也就是颜色。1 - Monochrome bitmap,4 - 16 color bitmap,8 - 256 color bitmap,F - 16位位图,18 - 24bit (true color) bitmap,20 - 32位位图。
001E-0021:数据压缩方式(数值位0:不压缩;1:8位压缩;2:4位压缩;3:Bitfields压缩)。
0022-0025:图像区数据的大小。单位字节,该数必须是4的倍数。 0026-0029:水平每米有多少像素,在设备无关位图(.DIB)中,每字节以00H填写。 002A-002D:垂直每米有多少像素,在设备无关位图(.DIB)中,每字节以00H填写。 002E-0031:此图像所用的颜色数。0032-0035:指定重要的颜色数。当该域的值等于颜色数时(或者等于0时),表示所有颜色都一样重要。
读取图片是注意跳过前18个字节,然后读出图片大小,图像数据区的大小与图片实际尺寸可能存在不一致,因为图片数据区字节数必须是4的倍数,所以后面可能有补零,需要舍弃。
其次,在通过读取四字节图片大小转化为int时需要注意byte值应该与0xff相与,否则可能出现负数,因为java采用补码存储数据。
package CZG;
import java.io.BufferedInputStream;import java.io.BufferedReader;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.awt.Color;public class BMPReader { /** * @param args * @return * @throws IOException */ public static int[][] ReadBMPPic(String src) throws IOException { FileInputStream fis=new FileInputStream(src); BufferedInputStream bis=new BufferedInputStream(fis); //丢掉文件头信息 bis.skip(18); //获取长度与宽度 byte[] b1=new byte[4]; bis.read(b1); byte[] b2=new byte[4]; bis.read(b2); int Width=byte2Int(b1); int Height=byte2Int(b2); System.out.println("Hight:"+Height+" Width:"+Width); //因为bmp位图的读取顺序为横向扫描,所以应把数组定义为int[Height][Width] int[][] data=new int[Height][Width]; int skipnum=0; //bmp图像区域的大小必须为4的倍数,而它以三个字节存一个像素,读的是偶应当跳过补上的0 if(Width*3%4!=0) { skipnum=4-Width*3%4; } System.out.println(skipnum); bis.skip(28); for(int i=0;i<data.length;i++) { for(int j=0;j<data[i].length;j++) { int red=bis.read(); int green=bis.read(); int blue=bis.read(); } if(skipnum!=0) { bis.skip(skipnum); } } bis.close(); return data; } private static int byte2Int(byte[] b) throws IOException { // TODO Auto-generated method stub int num=(b[3]&0xff<<24)|(b[2]&0xff)<<16|(b[1]&0xff)<<8|b[0]&0xff); return num; } public static void main(String[] args) throws IOException { // TODO Auto-generated method stub ReadBMPPic("LennaBinary.bmp"); }}