BMP由四部分組成 ,位圖文件頭 , 位圖信息頭 , 顏色 , 圖像數據區
BMP圖片是三個字節為一個顏色保存,將字節拼接為int需要使用位移來做
位圖文件頭 (12個字節):
0000-0001:文件標識,為字母ASCII碼“BM”,42 4D。
0002-0005:整個文件大小,單位字節。
0006-0009:這個位置的數字是被微軟保留的
000A-000D:記錄圖像數據區的起始位置。從文件開始到位圖數據(bitmap data)之間的偏移量。
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");
}
}
