Bitmap圖像到底是怎麼保存在電腦上的呢?它的二進制組成有什麼規則呢?顏色是怎麼保存起來的呢?等等一系列的問題。在本章分享中,將會爲你解決。
bmp圖像文件是怎麼構成的呢?下面我們來看一張圖:
所以一般bmp圖像有四部分組成。下面我們通過一個實例來解釋。
1.選好自己將進行實驗的照片,我準備了自己的8x8,16x16,32x32頭像
原圖 8x8 16x16
2.編寫讀取文件二進制流並在控制檯輸出的代碼。
public static void readFileBinary(String path){
File btp = new File(path);
FileInputStream btpInput;
if(btp!=null)
{
try {
btpInput = new FileInputStream(btp);
BufferedInputStream bufferedInputStream = new BufferedInputStream(btpInput);
int data;
int count=0;
try {
while((data=bufferedInputStream.read())!=-1)
{
if(count!=0&&count%16==0)
System.out.println("");
String str="";
if(data<16)
{
str+="0";
}
str+=Integer.toHexString(data);
System.out.print(str+" ");
count++;
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} catch (FileNotFoundException e) {
System.out.println("No file input!");
}
}else{
System.out.println("No file input!");
return ;
}
}
3.設置8x8的文件路徑,並執行程序。
根據輸出結果,首先解析文件頭信息。
42 4d:表明文件的類型,根據ASCII碼可以知道,這兩個字節表示BM,則表示了該文件爲bitmap文件。
00 00 00f6 :表明了文件的大小,0xf6轉化爲十進制表示246,則表示該文件總大小爲246個字節。我們可以比較一下。
可以看出文件的大小確實是246個字節。
00 00 00 00:這4個字節表示保留字節,也就是暫時還沒有使用到,可以用於拓展。
00 00 00 36:這4個字節表示該文件的數據區的偏移。表示從文件頭偏移0x36=48+6=54個字節就到了該文件的數據區。
到目前爲止,我們已經分析了14個字節的文件頭信息。那距離數據區54個字節,我們才走過了14個字節,那剩下的40個字節表示什麼意思呢?
下面來分析剩下的40個字節。
這40個字節,每4個字節組合在一起,表示一定的含義。
00 00 00 28:表示文件頭的字節數。0x28轉換爲十進制表示40,這是文件頭信息佔用40個字節。
00 00 00 08:表示圖像的寬度。很明顯0x8等於十進制的8,表示該圖像的寬度是8個像素。確實正確。
00 00 00 08:表示圖像的高度。與寬度同理。
00 18 00 01:這四個字節,要分爲前面兩個字節和後面兩個字節。前面兩個字節00 18轉換爲十進制等於24,則表示該圖像每個像素點佔用的比特數,在這裏每個像素點佔24個bits,也就是3個字節。後面00 01規定一直是這樣。
00 00 00 00:轉換爲十進制表示0,則表示不壓縮。那這四個字節到底有哪些情況呢?
有0(不壓縮),1(RLE 8,8位RLE壓縮),2(RLE 4,4位RLE壓縮,3(Bitfields,位域存放)。RLE簡單地說是採用像素數+像素值的方式進行壓縮。T408採用的是位域存放方式,用兩個字節表示一個像素,位域分配爲r5b6g5。
00 00 00 c0:這四個字節表示圖像的大小。我們來驗證一下。之前信息頭總共有54個字節,這個文件是246個,那246-54=192。那0xc0等於多少呢?192。所以很神奇。
00 00 0e c4:這個表示水平的分辨率。
00 00 0e c4:這個表示垂直的分辨率。
00 00 00 00:這個表示的是使用的顏色索引。在這個圖像中沒有使用到顏色索引,所以爲0
00 00 00 00:表示重要索引數,因爲連索引都沒有,更沒有重要索引了,於是和上面一個部分的結果時一樣的,也是0。
到目前爲止已經分析了文件的信息頭的信息。
那數據區是存放什麼信息呢?
我們知道顏色的組合分爲RGB。那這些數據區存放的信息就是每個像素點RGB的值。但是由於系統採用的是小端法進行存儲的。所以我們按順序讀出來的就是BGR了。
下面我們來看一下數據區中的BGR。
這選的圖像是8x8的,也就是一共有64個像素點,每個像素點是3個字節,那一共是192個字節,和前面解析出來的,圖像大小是192個字節,剛好吻合,好神奇吧。
那下面通過UltraEdit對該圖像文件的前32個像素點的BGR全部轉爲ff ff ff,看看會出現什麼情況。
圖像變成了這樣:
可以看到圖像的下面那一半已經變成了白色。感覺不太好看,下面把它編程黑色吧。
可以看到圖像的下面那一半已經變成了黑色。
16x16和圖像和32x32的圖像是一樣的。同理操作就可以了。