JAVA BMP解碼 超詳細解釋_第1頁
JAVA BMP解碼 超詳細解釋_第2頁
JAVA BMP解碼 超詳細解釋_第3頁
JAVA BMP解碼 超詳細解釋_第4頁
JAVA BMP解碼 超詳細解釋_第5頁
全文預覽已結束

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

./首先,對于BMP格式的圖片大家都不感覺到陌生吧。簡單的說明下:

BMP是一種與硬件設備無關的圖像文件格式,使用非常廣。它采用位映射存儲格式,除了圖像深度可選以外,不采用其他任何壓縮,因此,BMP文件所占用的空間很大。BMP文件的圖像深度可選lbit、4bit、8bit及24bit。BMP文件存儲數(shù)據(jù)時,圖像的掃描方式是按從左到右、從下到上的順序。

由于BMP文件格式是Windows環(huán)境換與圖有關的數(shù)據(jù)的一種標準,因此在Windows環(huán)境中運行的圖形圖像軟件都支持BMP圖像格式。要解析文件,就必須知道他的文件結構文件結構組成典型的BMP圖像文件由四部分組成:1:

位圖文件頭數(shù)據(jù)結構,它包含BMP圖像文件的類型、顯示容等信息;2:位圖信息數(shù)據(jù)結構,它包含有BMP圖像的寬、高、壓縮方法,以及定義顏色等信息;3:調色板,這個部分是可選的,有些位圖需要調色板,有些位圖,比如真彩色圖〔24位的BMP就不需要調色板;4:位圖數(shù)據(jù),這部分的容根據(jù)BMP位圖使用的位數(shù)不同而不同,在24位圖中直接使用RGB,而其他的小于24位的使用調色板中顏色索引值。

對應的數(shù)據(jù)結構1.BMP文件頭<14字節(jié)>BMP文件頭數(shù)據(jù)結構含有BMP文件的類型、文件大小和位圖起始位置等信息。其結構定義如下:IntbfType;

//

位圖文件的類型,必須為'B''M'兩個字母<0-1字節(jié)>IntbfSize;

//

位圖文件的大小,以字節(jié)為單位<2-5字節(jié)>usignedshort

bfReserved1;

//

位圖文件保留字,必須為0<6-7字節(jié)>usignedshort

bfReserved2;

//

位圖文件保留字,必須為0<8-9字節(jié)>IntbfOffBits;

//

位圖數(shù)據(jù)的起始位置,以相對于位圖<10-13字節(jié)>IntbfOffBits;//

文件頭的偏移量表示,以字節(jié)為單位2:位圖信息頭<40字節(jié)>BMP位圖信息頭數(shù)據(jù)用于說明位圖的尺寸等信息。IntSize;

//

本結構所占用字節(jié)數(shù)<14-17字節(jié)>Intimage_width;

//

位圖的寬度,以像素為單位<18-21字節(jié)>intimage_heigh;

//

位圖的高度,以像素為單位<22-25字節(jié)>IntPlanes;

//

目標設備的級別,必須為1<26-27字節(jié)>intnbiBitCount;//

每個像素所需的位數(shù),必須是1<雙色>,<28-29字節(jié)>//

4<16色>,8<256色>或24<真彩色>之一Int

biCompression;

//

位圖壓縮類型,必須是

0<不壓縮>,<30-33字節(jié)>//

1<BI_RLE8壓縮類型>或2<BI_RLE4壓縮類型>之一IntnSizeImage;

//

位圖的大小,以字節(jié)為單位<34-37字節(jié)>IntbiXPelsPerMeter;

//

位圖水平分辨率,每米像素數(shù)<38-41字節(jié)>Int

biYPelsPerMeter;

//

位圖垂直分辨率,每米像素數(shù)<42-45字節(jié)>Int

biClrUsed;//

位圖實際使用的顏色表中的顏色數(shù)<46-49字節(jié)>Int

biClrImportant;//

位圖顯示過程中重要的顏色數(shù)<50-53字節(jié)>3:顏色表顏色表用于說明位圖中的顏色,它有若干個表項,每一個表項是一個RGBQUAD類型的結構,定義一種顏色。class

RGBQUAD{byte

rgbBlue;//

藍色的亮度<值圍為0-255>byte

rgbGreen;

//

綠色的亮度<值圍為0-255>byte

rgbRed;

//

紅色的亮度<值圍為0-255>byte

rgbReserved;//

保留,必須為0}顏色表中RGBQUAD結構數(shù)據(jù)的個數(shù)有biBitCount來確定:當biBitCount=1,4,8時,分別有2,16,256個表項;當biBitCount=24時,沒有顏色表項。位圖信息頭和顏色表組成位圖信息,BITMAPINFO結構定義如下:class

BITMAPINFO{BITMAPINFOHEADER

bmiHeader;

//

位圖信息頭RGBQUAD

bmiColors[1];

//

顏色表}

4:位圖數(shù)據(jù)位圖數(shù)據(jù)記錄了位圖的每一個像素值,記錄順序是在掃描行是從左到右,掃描行之間是從下到上。位圖的一個像素值所占的字節(jié)數(shù):當biBitCount=1時,8個像素占1個字節(jié);當biBitCount=4時,2個像素占1個字節(jié);當biBitCount=8時,1個像素占1個字節(jié);當biBitCount=24時,1個像素占3個字節(jié);Windows規(guī)定一個掃描行所占的字節(jié)數(shù)必須是4的倍數(shù)<即以long為單位>,不足的以0填充,具體數(shù)據(jù)舉例:如某BMP文件開頭:424D

4690

0000

0000

0000

4600

0000

2800

0000

8000

0000

9000

0000

0100*1000

0300

0000

0090

0000

A00F

0000

A00F

0000

0000

0000

0000

0000*00F8

E007

1F00

0000*02F1

84F1

04F1

84F1

84F1

06F2

84F1

06F2

04F2

86F2

06F2

86F2

86F2

BMP文件可分為四個部分:位圖文件頭、位圖信息頭、彩色板、圖像數(shù)據(jù)陣列,在上圖中已用*分隔。

猥瑣分割線比方說,我們就可以做一個BMP圖片的查看器1、打開BMP文件時,我們這里選擇使用dataInputstream

讀取一個最常見的24位真彩色BMP圖片Java代碼//

創(chuàng)建文件輸入流java.io.FileInputStream

fis

=

new

java.io.FileInputStream<path>;

//

將文件流包裝成一個可以寫基本數(shù)據(jù)類型的輸出流

java.io.DataInputStream

dis

=

new

java.io.DataInputStream<fis>;

2、讀入BMP頭文件的基本信息Java代碼int

bflen=14;

byte

bf[]=new

byte[bflen];

dis.read<bf,0,bflen>;

//讀取14字節(jié)BMP文件頭

因為看到了BMP頭文件中沒有說明顯示圖片重要的信息,我只是開一個BF的數(shù)組,把頭文件信息讀取了出來,不做任何的處理。3、讀入位圖信息頭Java代碼int

bilen=40;

byte

bi[]=new

byte[bilen];

dis.read<bi,0,bilen>;//讀取40字節(jié)BMP信息頭

//

獲取一些重要數(shù)據(jù)

image_width=ChangeInt<bi,7>;

//源圖寬度

System.out.println<"寬:"+image_width>;

image_heigh=ChangeInt<bi,11>;

//源圖高度

System.out.println<"高:"+image_heigh>;

//位數(shù)

int

nbitcount=<<<int>bi[15]&0xff><<8>

|

<int>bi[14]&0xff;

System.out.println<"位數(shù):"+nbitcount>;

//源圖大小

int

nsizeimage=ChangeInt<bi,23>;

System.out.println<"源圖大小:"+nsizeimage>;

由位圖信息頭中我們也可以看出來,要顯示圖片,重要的信息也就只有幾個,其他都是一些不重要的,我們直接忽略掉。因為我是直接讀取40位的信息頭所以要將一些byte轉為int

即ChangeInt即

4個byte

>

一個intJava代碼//轉成int

public

int

ChangeInt<byte[]

bi,int

start>{

return

<<<int>bi[start]&0xff><<24>

|

<<<int>bi[start-1]&0xff><<16>

|

<<<int>bi[start-2]&0xff><<8>

|

<int>bi[start-3]&0xff;

}

因為24為的沒有顏色表,所以我們直接讀位圖數(shù)據(jù)

最后,最關鍵的就是,讀取位圖數(shù)據(jù)Java代碼public

void

showRGB24<DataInputStream

dis>

throws

IOException{

this.setTitle<path>;

//彈出一個圖片的窗口一個大小

this.setSize<image_width,

image_heigh>;

this.setResizable<false>;

this.setVisible<true>;

g=this.getGraphics<>;

if<!<image_width*3

%

4==0>>{//圖片的寬度不為0

skip_width

=4-image_width*3%4;

}//判斷是否后面有補0

的情況

//裝載RGB顏色的數(shù)據(jù)數(shù)組

imageR

=

new

int[image_heigh][image_width];

imageG

=

new

int[image_heigh][image_width];

imageB

=

new

int[image_heigh][image_width];

//按行讀取

如果H,W為正則倒著來

for

<int

h=image_heigh-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;

if<w==0>{//跳過補0項

System.out.println<dis.skipBytes<skip_width>>;

}

}

}

repaint<>;

}

關鍵就是在于

位圖是否有補0有則要跳過,沒有就直接讀,不然顯示出來的BMP圖像會傾斜。即注釋掉這句話得到的效果Java代碼if<w==0>{

System.out.println<dis.skipBytes<skip_width>>;

}

最后paint<>中顯示就可以看見圖片了Java代碼

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論