版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
媒體數(shù)據(jù)格式解析分析未知文件數(shù)據(jù)結(jié)構(gòu)格式時(shí)需要熟悉不同文件類型的一種或多種該類公開文件的數(shù)據(jù)存儲(chǔ)格式,因?yàn)橥ǔG闆r下未知文件數(shù)據(jù)結(jié)構(gòu)格式很可能是在公開的文件格式上建立起來(lái)的,或只稍微修改了一些地方。編程人員一般不會(huì)自己發(fā)明一種文件格式,因?yàn)榫幊倘藛T大多數(shù)都很"懶",他們通常的做法是參考一些公開文件的格式,稍微修改一下。例如,如果要分析的未知文件格式是屬于圖像類的,那么這個(gè)未知的圖像文件格式必定與BMP文件格式有相似的地方。熟悉BMP格式對(duì)研究和分析這個(gè)未知的圖像文件格式有極大的幫助,如果掌握了BMP圖像文件存儲(chǔ)格式就可以利用BMP格式去匹配和猜測(cè)未知圖像文件格式。例如,如要分析的未知文件格式是屬于3D模型的,那么這個(gè)未知的3D模型文件格式必定與3DS和X文件格式有相似的地方,所以研究未知的3D模型文件前需要先參考和學(xué)習(xí)一些常見(jiàn)的公開格式的模型文件,這與解密某個(gè)加密算法之前需要研究一些公開的加密算法是同一個(gè)道理。因?yàn)楸緯轻槍?duì)游戲資源文件解密,所以下面將要介紹和分析游戲資源文件的常用文件存儲(chǔ)格式。游戲資源文件大體上可以歸到多媒體數(shù)據(jù)格式上,學(xué)習(xí)和研究這些多媒體文件格式對(duì)日后分析未知的游戲資源文件格式有很大幫助。通過(guò)本章的學(xué)習(xí)讀者可以掌握以下內(nèi)容:BMP圖像文件格式;PNG圖像文件格式;X模型文件格式;md3模型文件格式。BMP圖像文件格式BMP圖像文件格式是游戲中常用的圖像資源文件格式,BMP圖像文件起源早,程序員對(duì)BMP都比較熟悉,再加上BMP格式簡(jiǎn)單,讀取和寫入非常容易實(shí)現(xiàn),所以無(wú)論Windows的還是DriectX,都有支持讀取和寫入BMP文件格式的API函數(shù)。針對(duì)BMP壓縮的算法比較成熟,壓縮效果也不差,而且都是無(wú)損壓縮編碼,即可以100%還原BMP圖像質(zhì)量。雖然JPG格式壓縮效果比較理想,但游戲編程人員一般極少使用,因?yàn)镴PG要犧牲圖像的質(zhì)量來(lái)?yè)Q取大的壓縮率,加上JPG解碼速度較慢和格式復(fù)雜,所以游戲中使用JPG格式的圖像的情況不多(筆者目前只發(fā)現(xiàn)一款網(wǎng)絡(luò)游戲使用JPG格式作為游戲里的圖像格式,并且使用額外的數(shù)據(jù)保存了圖像中的透明通道信息來(lái)讓JPG支持透明色)。GIF格式雖然支持多幀動(dòng)畫效果,但GIF最大僅支持256色,不能表達(dá)色彩豐富的圖像,所以對(duì)于對(duì)速度要求非??量潭覉D像質(zhì)量要高的游戲來(lái)說(shuō),使用BMP格式存儲(chǔ)圖像是不錯(cuò)的選擇。BMP圖像文件介紹MP圖像文件格式是微軟公司發(fā)明的,BMP圖像文件的后綴名通常是.BMP,但也有少數(shù)是.DIP。不過(guò)單憑文件的后綴名并不能惟一確定是不是BMP圖像文件,要惟一確定BMP圖像文件還需要分析文件的存儲(chǔ)格式。BMP圖像文件和GIF圖像文件不同,BMP圖像文件只能存儲(chǔ)一幅圖像,即一幀。GIF圖像文件能保存多幀圖像,從而可以實(shí)現(xiàn)動(dòng)畫的效果。BMP圖像文件支持單色、16色、256色和真彩色4種顏色的圖像。BMP圖像的數(shù)據(jù)即可壓縮也可以不壓縮,如果選擇了壓縮數(shù)據(jù),那么根據(jù)顏色的不同,BMP使用不同的RLE壓縮方式。RLE是一種無(wú)損壓縮方法,使用RLE壓縮的數(shù)據(jù)能完整還原。如果圖像是16色,則可以采用RLE4壓縮,如果圖像是256色,則可以采用RLE8壓縮,真彩色的圖像不使用壓縮。BMP的圖像數(shù)據(jù)排列方式有點(diǎn)特別,BMP的圖像數(shù)據(jù)排列方式首先從圖像的左下角第一個(gè)像素開始存儲(chǔ)每一行數(shù)據(jù),即BMP圖像數(shù)據(jù)存儲(chǔ)的最后一個(gè)像素等于實(shí)際圖像的右上角第一個(gè)像素。BMP圖像文件存儲(chǔ)結(jié)構(gòu)(1)BMP文件存儲(chǔ)結(jié)構(gòu)的格式可以在Windows中的WINGDI.h文件中找到定義。BMP文件總體上由4部分組成,分別是位圖文件頭、位圖信息頭、調(diào)色板和圖像數(shù)據(jù),如表5-1所示。表5-1BMP文件的組成結(jié)構(gòu)位圖文件頭(bitmap-fileheader)位圖信息頭(bitmap-informationheader)彩色表/調(diào)色板(colortable)位圖數(shù)據(jù)(bitmap-data)下面來(lái)詳細(xì)看一下每個(gè)組成部分的細(xì)節(jié)。位圖文件頭(bitmap-fileheader)位圖文件頭(bitmap-fileheader)包含了圖像類型、圖像大小、圖像數(shù)據(jù)存放地址和兩個(gè)保留未使用的字段。打開WINGDI.h文件,搜索"BITMAPFILEHEADER"就可以定位到BMP文件的位圖文件頭的數(shù)據(jù)結(jié)構(gòu)定義。typedefstructtagBITMAPFILEHEADER{
WORDbfType;
DWORDbfSize;
WORDbfReserved1;
WORDbfReserved2;
DWORDbfOffBits;
}BITMAPFILEHEADER,FAR*LPBITMAPFILEHEADER,*PBITMAPFILEHEADER;列出了tagBITMAPFILEHEADER中各字段的含義。tagBITMAPFILEHEADER結(jié)構(gòu)字段名大?。▎挝唬鹤止?jié))描述bfType2位圖類別,根據(jù)不同的操作系統(tǒng)而不同,在Windows中,此字段的值總為‘BM’bfSize4BMP圖像文件的大小bfReserved12總為0bfReserved22總為0bfOffBits4BMP圖像數(shù)據(jù)的地址位圖信息頭(bitmap-informationheader)位圖信息頭(bitmap-informationheader)包含了位圖信息頭的大小、圖像的寬高、圖像的色深、壓縮說(shuō)明圖像數(shù)據(jù)的大小和其他一些參數(shù)。打開WINGDI.h文件,搜索"tagBITMAPINFOHEADER"就可以定位到BMP文件的位圖信息頭的數(shù)據(jù)結(jié)構(gòu)定義。typedefstructtagBITMAPINFOHEADER{
DWORDbiSize;
LONGbiWidth;
LONGbiHeight;
WORDbiPlanes;
WORDbiBitCount;
DWORDbiCompression;
DWORDbiSizeImage;
LONGbiXPelsPerMeter;
LONGbiYPelsPerMeter;
DWORDbiClrUsed;
DWORDbiClrImportant;
}BITMAPINFOHEADER,FAR*LPBITMAPINFOHEADER,*PBITMAPINFOHEADER;列出了tagBITMAPFILEHEADER中各字段的含義。tagBITMAPFILEHEADER結(jié)構(gòu)字段名大?。▎挝唬鹤止?jié))描述biSize4本結(jié)構(gòu)的大小,根據(jù)不同的操作系統(tǒng)而不同,在Windows中,此字段的值總為28h字節(jié)=40字節(jié)biWidth4BMP圖像的寬度,單位像素biHeight4BMP圖像的高度,單位像素biPlanes2位圖的位面數(shù),總為1biBitCount2BMP圖像的色深,即一個(gè)像素用多少位表示,常見(jiàn)有1、4、8、16、24和32,分別對(duì)應(yīng)單色、16色、256色、16位高彩色、24位真彩色和32位增強(qiáng)型真彩色biCompression4壓縮方式,0表示不壓縮,1表示RLE8壓縮,2表示RLE4壓縮,3表示每個(gè)像素值由指定的掩碼決定biSizeImage4BMP圖像數(shù)據(jù)大小,必須是4的倍數(shù),圖像數(shù)據(jù)大小不是4的倍數(shù)時(shí)用0填充補(bǔ)足biXPelsPerMeter4水平分辨率,單位像素/mbiYPelsPerMeter4垂直分辨率,單位像素/mbiClrUsed4BMP圖像使用的顏色,0表示使用全部顏色,對(duì)于256色位圖來(lái)說(shuō),此值為100h=256biClrImportant4重要的顏色數(shù),此值為0時(shí)所有顏色都重要,對(duì)于使用調(diào)色板的BMP圖像來(lái)說(shuō),當(dāng)顯卡不能夠顯示所有顏色時(shí),此值將輔助驅(qū)動(dòng)程序顯示顏色BMP圖像文件存儲(chǔ)結(jié)構(gòu)(2)彩色表/調(diào)色板(colortable)彩色表/調(diào)色板(colortable)是單色、16色和256色圖像文件所特有的,相對(duì)應(yīng)的調(diào)色板大小是2、16和256,調(diào)色板以4字節(jié)為單位,每4個(gè)字節(jié)存放一個(gè)顏色值,圖像的數(shù)據(jù)是指向調(diào)色板的索引??梢詫⒄{(diào)色板想象成一個(gè)數(shù)組,每個(gè)數(shù)組元素的大小為4字節(jié),假設(shè)有一256色的BMP圖像的調(diào)色板數(shù)據(jù)為:調(diào)色板[0]=黑、調(diào)色板[1]=白、調(diào)色板[2]=紅、調(diào)色板[3]=藍(lán)…調(diào)色板[255]=黃圖像數(shù)據(jù)010002FF表示調(diào)用調(diào)色板[1]、調(diào)色板[0]、調(diào)色板[2]和調(diào)色板[255]中的數(shù)據(jù)來(lái)顯示圖像顏色。在早期的計(jì)算機(jī)中,顯卡相對(duì)比較落后,不一定能保證顯示所有顏色,所以在調(diào)色板中的顏色數(shù)據(jù)應(yīng)盡可能將圖像中主要的顏色按順序排列在前面,位圖信息頭的biClrImportant字段指出了有多少種顏色是重要的。每個(gè)調(diào)色板的大小為4字節(jié),按藍(lán)、綠、紅存儲(chǔ)一個(gè)顏色值。打開WINGDI.h文件,搜索"tagRGBTRIPLE"就可以定位到BMP文件的調(diào)色板的數(shù)據(jù)結(jié)構(gòu)定義。typedefstructtagRGBQUAD{
BYTErgbBlue;
BYTErgbGreen;
BYTErgbRed;
BYTErgbReserved;
}RGBQUAD;列出了tagRGBTRIPLE中各字段的含義。tagRGBTRIPLE結(jié)構(gòu)字段名大?。▎挝唬鹤止?jié))描述rgbBlue1藍(lán)色值rgbGreen1綠色值rgbRed1紅色值rgbReserved1保留,總為0位圖數(shù)據(jù)(bitmap-data)如果圖像是單色、16色和256色,則緊跟著調(diào)色板的是位圖數(shù)據(jù),位圖數(shù)據(jù)是指向調(diào)色板的索引序號(hào)。如果位圖是16位、24位和32位色,則圖像文件中不保留調(diào)色板,即不存在調(diào)色板,圖像的顏色直接在位圖數(shù)據(jù)中給出。16位圖像使用2字節(jié)保存顏色值,常見(jiàn)有兩種格式:5位紅5位綠5位藍(lán)和5位紅6位綠5位藍(lán),即555格式和565格式。555格式只使用了15位,最后一位保留,設(shè)為0。24位圖像使用3字節(jié)保存顏色值,每一個(gè)字節(jié)代表一種顏色,按紅、綠、藍(lán)排列。32位圖像使用4字節(jié)保存顏色值,每一個(gè)字節(jié)代表一種顏色,除了原來(lái)的紅、綠、藍(lán),還有Alpha通道,即透明色。如果圖像帶有調(diào)色板,則位圖數(shù)據(jù)可以根據(jù)需要選擇壓縮與不壓縮,如果選擇壓縮,則根據(jù)BMP圖像是16色或256色,采用RLE4或RLE8壓縮算法壓縮。RLE4是壓縮16色圖像數(shù)據(jù)的,RLE4采用表5-5所示方式壓縮數(shù)據(jù)。表5-5RLE4壓縮方法方案1字節(jié)2字節(jié)3字節(jié)4字節(jié)N字節(jié)A重復(fù)次數(shù)顏色索引B設(shè)為0后面有效的顏色索引數(shù)顏色索引顏色索引顏色索引…假設(shè)有如下16色位圖數(shù)據(jù),共20字節(jié),數(shù)據(jù)使用了RLE4壓縮:0500040500080905040004050809040807010000數(shù)據(jù)解壓時(shí)首先讀取05,因?yàn)?5不等于0,所以選擇A方案,根據(jù)A方案,05表示后面數(shù)據(jù)重復(fù)的次數(shù),接著讀取00,00表示有兩個(gè)顏色索引,每個(gè)索引占4位,第一個(gè)像素在高4位,第二個(gè)像素在低4位,即在一個(gè)字節(jié)中低像素在高位,高像素在低位。0500解壓后等于00000。讀取04,選擇A方案,按照上面的操作解析,04是后面數(shù)據(jù)重復(fù)的次數(shù),05是兩個(gè)顏色索引,第3個(gè)顏色索引為5,第4個(gè)顏色索引為0。0405解壓后等于0505。讀取00,選擇B方案,讀取08,08表示后面有效的顏色索引數(shù)。0008解壓后等于09050400。讀取04,選擇A方案,按照上面的操作解析,04是后面數(shù)據(jù)重復(fù)的次數(shù),05是兩個(gè)顏色索引。0405解壓后等于0505。讀取08,選擇A方案,按照上面的操作解析,08是后面數(shù)據(jù)重復(fù)的次數(shù),09是兩個(gè)顏色索引。0809解壓后等于09090909。
讀取04,選擇A方案,按照上面的操作解析,04是后面數(shù)據(jù)重復(fù)的次數(shù),08是兩個(gè)顏色索引。0408解壓后等于0808。讀取07,選擇A方案,按照上面的操作解析,07是后面數(shù)據(jù)重復(fù)的次數(shù),01是兩個(gè)顏色索引。0701解壓后等于0101010。讀取00,選擇B方案,讀取00,00表示后面有效的顏色索引數(shù),0表示無(wú),即解壓完一行數(shù)據(jù)。綜合上面的操作,解壓后的數(shù)據(jù)為:0000005050905040005050909090908080101010看上去和原來(lái)的數(shù)據(jù)大小一樣,沒(méi)有體現(xiàn)到壓縮效果,這是因?yàn)樯厦娴睦又贿x擇了20字節(jié)數(shù)據(jù),而且這20字節(jié)數(shù)據(jù)中重復(fù)的數(shù)據(jù)不多,使用RLE壓縮重復(fù)數(shù)據(jù)不多的數(shù)據(jù)時(shí),有時(shí)可能壓縮后的大小反而比原來(lái)的數(shù)據(jù)還大。其實(shí)一般情況下當(dāng)數(shù)據(jù)比較多而且重復(fù)的時(shí)候,使用RLE壓縮效果還是比較理想的。RLE8的壓縮方式可以參考上面的RLE4解壓方法,惟一的區(qū)別是RLE8使用1個(gè)字節(jié)存放顏色索引,而RLE4使用4位存放顏色索引。分析BMP圖像文件結(jié)構(gòu)(1)結(jié)合上面對(duì)BMP文件的分析,下面分別對(duì)256色和24位色的BMP圖像進(jìn)行十六進(jìn)制分析,通過(guò)在十六進(jìn)制編輯器中分析文件結(jié)構(gòu),能夠增加分析文件的經(jīng)驗(yàn)。如圖5-1和圖5-2所示,分別為256色BMP圖像cat2.bmp和24位色BMP圖像cat1.bmp。其中cat2.bmp圖像的分辨率為200×153,文件大小為31680字節(jié)。cat1.bmp圖像的分辨率為200×150,文件大小為90056字節(jié)。圖5-1cat2.bmp圖像圖5-2cat1.bmp圖像現(xiàn)在來(lái)分析cat2.bmp的圖像文件,在Winhex中打開cat2.bmp,如圖5-3所示。(點(diǎn)擊查看大圖)圖5-3在Winhex中打開cat2.bmp圖像文件首先分析位圖文件頭的結(jié)構(gòu),如圖5-4所示。根據(jù)BMP文件的位圖文件頭結(jié)構(gòu)定義分析出cat2.bmp圖像的位圖文件頭中各字段的含義,如表5-6所示。(點(diǎn)擊查看大圖)圖5-4cat2.bmp圖像文件的位圖文件頭表5-6cat2.bmp圖像文件中位圖文件頭各字段的含義十六進(jìn)制值描述424D:BM的ASCII值,在Windows中的BMP文件標(biāo)識(shí)符C07B00007BC0h=31680,是cat2文件的大小00000000保留值,總為0360400436h=1078,是圖像數(shù)據(jù)的地址,即文件頭+信息頭+調(diào)色板的長(zhǎng)度分析BMP圖像文件結(jié)構(gòu)(2)繼續(xù)分析接下來(lái)的數(shù)據(jù),根據(jù)BMP文件結(jié)構(gòu)的定義,接下來(lái)的數(shù)據(jù)是位圖信息頭,cat2.bmp圖像文件的位圖信息頭的內(nèi)容如圖5-5所示。(點(diǎn)擊查看大圖)圖5-5cat2.bmp圖像的位圖信息頭表5-7所示為cat2.bmp圖像文件中位圖信息頭各字段的含義。表5-7cat2.bmp圖像文件中位圖信息頭各字段的含義十六進(jìn)制值描述28000000:cat2.bmp圖像的位圖信息頭大小C8000000000000C8=200,是cat2圖像的寬度,單位像素9900000000000099=153,是cat2圖像的高度,單位像素0100總是108000008=8,cat2圖像的色深,即2的8次冪等于256色00000000壓縮方式,0表示不壓縮8A7700000000778A=30602,是cat2圖像的圖像數(shù)據(jù)大小,單位字節(jié)120B000000000B12=2834,cat2圖像的水平分辨率,單位像素/m120B000000000B12=2834,cat2圖像的垂直分辨率,單位像素/m00000000cat2圖像使用的顏色數(shù),0表示使用全部顏色00000000cat2圖像中重要的顏色數(shù),0表示所有顏色都重要繼續(xù)分析接下來(lái)的數(shù)據(jù),根據(jù)BMP文件結(jié)構(gòu)的定義,因?yàn)閏at2.bmp圖像是256色的位圖,所以應(yīng)該有256個(gè)調(diào)色板,每個(gè)調(diào)色板占4字節(jié),整個(gè)調(diào)色板一共1024字節(jié)大小。cat2.bmp圖像文件的調(diào)色板數(shù)據(jù)如圖5-6和圖5-7所示。(點(diǎn)擊查看大圖)圖5-6cat2.bmp圖像的調(diào)色板地址從00000036h開始存儲(chǔ)(點(diǎn)擊查看大圖)圖5-7cat2.bmp圖像的調(diào)色板數(shù)據(jù)結(jié)束地址是00000435h從圖5-6和圖5-7中可以看出,cat2.bmp圖像的調(diào)色板地址從00000036h開始到00000435h結(jié)束,即00000435h-00000036h+1=400h=1024。如果想查看cat2圖像的調(diào)色板對(duì)應(yīng)的實(shí)際顯示顏色,可以使用AdobePhotoshopCS打開cat2.bmp,在AdobePhotoshopCS的菜單欄中選擇"圖像"→"模式"→"顏色表",即可觀看cat2的調(diào)色板,如圖5-8所示。圖5-8在AdobePhotoshopCS中查看cat2的調(diào)色板分析BMP圖像文件結(jié)構(gòu)(3)圖5-8所示cat2.bmp的調(diào)色板顏色和圖5-6中的十六進(jìn)制數(shù)據(jù)是一一對(duì)應(yīng)的。在AdobePhotoshopCS的調(diào)色板上單擊任何一個(gè)像素的顏色即可彈出一個(gè)拾色器對(duì)話框顯示該像素顏色的詳細(xì)組成信息。cat2.bmp調(diào)色板和cat2.bmp的十六進(jìn)制數(shù)據(jù)的對(duì)應(yīng)關(guān)系如圖5-9所示。繼續(xù)分析接下來(lái)的數(shù)據(jù),根據(jù)BMP文件結(jié)構(gòu)的定義,如果一個(gè)圖像有調(diào)色板,那么緊跟在調(diào)色板后面的是圖像的數(shù)據(jù),這些數(shù)據(jù)不是實(shí)際的顏色值,而是指向調(diào)色板數(shù)組的索引,根據(jù)索引來(lái)獲取調(diào)色板中的顏色,如圖5-10所示。(點(diǎn)擊查看大圖)圖5-9cat2.bmp調(diào)色板和cat2.bmp的十六進(jìn)制數(shù)據(jù)的對(duì)應(yīng)關(guān)系(點(diǎn)擊查看大圖)圖5-10cat2.bmp的圖像數(shù)據(jù)因?yàn)閏at2.bmp是256色的位圖,即采用了8位色深作為指向調(diào)色板數(shù)組的索引,所以根據(jù)圖5-10中顯示的數(shù)據(jù)可以得知:494949B1494949494999表示cat2.bmp位圖左下角第1個(gè)像素的顏色等于調(diào)色板[49],第2個(gè)像素的顏色等于調(diào)色板[49],第3個(gè)像素的顏色等于調(diào)色板[49],第4個(gè)像素的顏色等于調(diào)色板[B1]……依此類推。分析完cat2.bmp圖像之后,接下來(lái)分析的是cat1.bmp。cat1.bmp圖像是24位色圖像,根據(jù)BMP文件結(jié)構(gòu)定義得知,cat1.bmp圖像沒(méi)有調(diào)色板,圖像數(shù)據(jù)存儲(chǔ)的是實(shí)際的顏色數(shù)據(jù),每個(gè)像素用3字節(jié)表示,分別是紅綠藍(lán)。由于cat1.bmp和cat2.bmp的位圖文件頭和位圖信息頭結(jié)構(gòu)一樣,所以cat1.bmp的位圖文件頭和位圖信息頭可以參考上面對(duì)cat2.bmp的分析,下面從cat1.bmp的位圖信息頭結(jié)束的位置開始分析,如圖5-11所示。(點(diǎn)擊查看大圖)圖5-11cat1.bmp圖像的圖像數(shù)據(jù)從圖5-11可以看到表示每個(gè)像素的紅綠藍(lán)三色的值,實(shí)際存放的時(shí)候是倒過(guò)來(lái)存放的,在分析BMP圖像格式時(shí)需要注意這點(diǎn)。通過(guò)上面對(duì)BMP文件存儲(chǔ)結(jié)構(gòu)的分析發(fā)現(xiàn),BMP文件的位圖文件頭和位圖信息頭存在著大量的重復(fù)數(shù)據(jù)。如果存儲(chǔ)大量同一色深的BMP位圖,必然會(huì)浪費(fèi)大量存儲(chǔ)空間,所以很多時(shí)候游戲編程人員都會(huì)去掉BMP文件頭和信息頭,只保留幾個(gè)必要的信息和圖像數(shù)據(jù),那么BMP文件頭和信息頭中哪幾個(gè)字段是必須保留的呢?使用Winhex的文件比較功能比較兩個(gè)24位色深的BMP圖像文件,觀察兩個(gè)文件的文件頭和信息頭有什么不同的地方,如圖5-12所示。(點(diǎn)擊查看大圖)圖5-12使用Winhex比較兩個(gè)24位色深的BMP圖像文件從圖5-12可以看出,兩個(gè)色深相同的BMP圖像的文件頭和信息頭一共有4處不同的地方,分別是文件頭的文件大小、信息頭的圖像寬度、圖像高度和圖像數(shù)據(jù)大小。所以很多時(shí)候,游戲編程人員只保留圖像文件的文件大小、圖像寬度、圖像高度和圖像數(shù)據(jù)大小信息,甚至有時(shí)不需要保留文件大小這個(gè)數(shù)值,使用圖像數(shù)據(jù)大小數(shù)值即可。在分析未知文件存儲(chǔ)格式時(shí),如果遇到去掉了文件頭的文件時(shí),如上面所說(shuō)的BMP文件,會(huì)給分析未知文件格式帶來(lái)一定的困難。這時(shí)需要使用十六進(jìn)制編輯器的文件比較功能,觀察兩個(gè)同類的未知文件格式尋找某些潛在的規(guī)律,如果實(shí)在觀察不出規(guī)律的,那只能使用白盒分析方法,對(duì)調(diào)用此未知文件格式的程序進(jìn)行反匯編跟蹤調(diào)試了。當(dāng)然,有時(shí)靈感和運(yùn)氣也很重要。CreateDIBSection理解分辨率我們常說(shuō)的屏幕分辨率為640×480,刷新頻率為70Hz,意思是說(shuō)每行要掃描640個(gè)象素,一共有480行,每秒重復(fù)掃描屏幕70次。理解調(diào)色板有一個(gè)長(zhǎng)寬各為200個(gè)象素,顏色數(shù)為16色的彩色圖,每一個(gè)象素都用R、G、B三個(gè)分量表示。因?yàn)槊總€(gè)分量有256個(gè)級(jí)別,要用8位(bit),即一個(gè)字節(jié)(byte)來(lái)表示,所以每個(gè)象素需要用3個(gè)字節(jié)。整個(gè)圖象要用200×200×3,約120k字節(jié),可不是一個(gè)小數(shù)目呀!如果我們用下面的方法,就能省的多。因?yàn)槭且粋€(gè)16色圖,也就是說(shuō)這幅圖中最多只有16種顏色,我們可以用一個(gè)表:表中的每一行記錄一種顏色的R、G、B值。這樣當(dāng)我們表示一個(gè)象素的顏色時(shí),只需要指出該顏色是在第幾行,即該顏色在表中的索引值。舉個(gè)例子,如果表的第0行為255,0,0(紅色),那么當(dāng)某個(gè)象素為紅色時(shí),只需要標(biāo)明0即可。讓我們?cè)賮?lái)計(jì)算一下:16種狀態(tài)可以用4位(bit)表示,所以一個(gè)象素要用半個(gè)字節(jié)。整個(gè)圖象要用200×200×0.5,約20k字節(jié),再加上表占用的字節(jié)為3×16=48字節(jié).整個(gè)占用的字節(jié)數(shù)約為前面的1/6,省很多吧?這張R、G、B的表,就是我們常說(shuō)的調(diào)色板(Palette),另一種叫法是顏色查找表LUT(LookUpTable),似乎更確切一些。Windows位圖中便用到了調(diào)色板技術(shù)。其實(shí)不光是Windows位圖,許多圖象文件格式如pcx、tif、gif等都用到了。所以很好地掌握調(diào)色板的概念是十分有用的。有一種圖,它的顏色數(shù)高達(dá)256×256×256種,也就是說(shuō)包含我們上述提到的R、G、B顏色表示方法中所有的顏色,這種圖叫做真彩色圖(truecolor)。真彩色圖并不是說(shuō)一幅圖包含了所有的顏色,而是說(shuō)它具有顯示所有顏色的能力,即最多可以包含所有的顏色。表示真彩色圖時(shí),每個(gè)象素直接用R、G、B三個(gè)分量字節(jié)表示,而不采用調(diào)色板技術(shù)。原因很明顯:如果用調(diào)色板,表示一個(gè)象素也要用24位,這是因?yàn)槊糠N顏色的索引要用24位(因?yàn)榭偣灿?24種顏色,即調(diào)色板有224行),和直接用R,G,B三個(gè)分量表示用的字節(jié)數(shù)一樣,不但沒(méi)有任何便宜,還要加上一個(gè)256×256×256×3個(gè)字節(jié)的大調(diào)色板。所以真彩色圖直接用R、G、B三個(gè)分量表示,它又叫做24位色圖。bmp文件格式介紹完位圖和調(diào)色板的概念,下面就讓我們來(lái)看一看Windows的位圖文件(.bmp文件)的格式是什么樣子的。bmp文件大體上分成四個(gè)部分,如圖1.3所示。位圖文件頭BITMAPFILEHEADER位圖信息頭BITMAPINFOHEADER調(diào)色板Palette實(shí)際的位圖數(shù)據(jù)ImageDate圖1.3Windows位圖文件結(jié)構(gòu)示意圖第一部分為位圖文件頭BITMAPFILEHEADER,是一個(gè)結(jié)構(gòu),其定義如下:typedefstructtagBITMAPFILEHEADER{WORD bfType;DWORD bfSize;WORD bfReserved1;WORD bfReserved2;DWORD bfOffBits;}BITMAPFILEHEADER;這個(gè)結(jié)構(gòu)的長(zhǎng)度是固定的,為14個(gè)字節(jié)(WORD為無(wú)符號(hào)16位整數(shù),DWORD為無(wú)符號(hào)32位整數(shù)),各個(gè)域的說(shuō)明如下:bfType指定文件類型,必須是0x424D,即字符串“BM”,也就是說(shuō)所有.bmp文件的頭兩個(gè)字節(jié)都是“BM”。bfSize指定文件大小,包括這14個(gè)字節(jié)。bfReserved1,bfReserved2為保留字,不用考慮bfOffBits為從文件頭到實(shí)際的位圖數(shù)據(jù)的偏移字節(jié)數(shù),即圖1.3中前三個(gè)部分的長(zhǎng)度之和。第二部分為位圖信息頭BITMAPINFOHEADER,也是一個(gè)結(jié)構(gòu),其定義如下:typedefstructtagBITMAPINFOHEADER{DWORD biSize;LONG biWidth;LONG biHeight;WORD biPlanes;WORD biBitCountDWORD biCompression;DWORD biSizeImage;LONG biXPelsPerMeter;LONG biYPelsPerMeter;DWORD biClrUsed;DWORD biClrImportant;}BITMAPINFOHEADER;這個(gè)結(jié)構(gòu)的長(zhǎng)度是固定的,為40個(gè)字節(jié)(LONG為32位整數(shù)),各個(gè)域的說(shuō)明如下:biSize指定這個(gè)結(jié)構(gòu)的長(zhǎng)度,為40。biWidth指定圖象的寬度,單位是象素。biHeight指定圖象的高度,單位是象素。biPlanes必須是1,不用考慮。biBitCount指定表示顏色時(shí)要用到的位數(shù),常用的值為1(黑白二色圖),4(16色圖),8(256色),24(真彩色圖)(新的.bmp格式支持32位色,這里就不做討論了)。biCompression指定位圖是否壓縮,有效的值為BI_RGB,BI_RLE8,BI_RLE4,BI_BITFIELDS(都是一些Windows定義好的常量)。要說(shuō)明的是,Windows位圖可以采用RLE4,和RLE8的壓縮格式,但用的不多。我們今后所討論的只有第一種不壓縮的情況,即biCompression為BI_RGB的情況。biSizeImage指定實(shí)際的位圖數(shù)據(jù)占用的字節(jié)數(shù),其實(shí)也可以從以下的公式中計(jì)算出來(lái):biSizeImage=biWidth’×biHeight要注意的是:上述公式中的biWidth’必須是4的整倍數(shù)(所以不是biWidth,而是biWidth’,表示大于或等于biWidth的,最接近4的整倍數(shù)。舉個(gè)例子,如果biWidth=240,則biWidth’=240;如果biWidth=241,biWidth’=244)。如果biCompression為BI_RGB,則該項(xiàng)可能為零biXPelsPerMeter指定目標(biāo)設(shè)備的水平分辨率,單位是每米的象素個(gè)數(shù),關(guān)于分辨率的概念,我們將在第4章詳細(xì)介紹。biYPelsPerMeter指定目標(biāo)設(shè)備的垂直分辨率,單位同上。biClrUsed指定本圖象實(shí)際用到的顏色數(shù),如果該值為零,則用到的顏色數(shù)為2biBitCount。biClrImportant指定本圖象中重要的顏色數(shù),如果該值為零,則認(rèn)為所有的顏色都是重要的。第三部分為調(diào)色板Palette,當(dāng)然,這里是對(duì)那些需要調(diào)色板的位圖文件而言的。有些位圖,如真彩色圖,前面已經(jīng)講過(guò),是不需要調(diào)色板的,BITMAPINFOHEADER后直接是位圖數(shù)據(jù)。調(diào)色板實(shí)際上是一個(gè)數(shù)組,共有biClrUsed個(gè)元素(如果該值為零,則有2biBitCount個(gè)元素)。數(shù)組中每個(gè)元素的類型是一個(gè)RGBQUAD結(jié)構(gòu),占4個(gè)字節(jié),其定義如下:typedefstructtagRGBQUAD{BYTErgbBlue; //該顏色的藍(lán)色分量BYTErgbGreen; //該顏色的綠色分量BYTErgbRed; //該顏色的紅色分量BYTErgbReserved; /保留值}RGBQUAD;第四部分就是實(shí)際的圖象數(shù)據(jù)了。對(duì)于用到調(diào)色板的位圖,圖象數(shù)據(jù)就是該象素顏在調(diào)色板中的索引值。對(duì)于真彩色圖,圖象數(shù)據(jù)就是實(shí)際的R、G、B值。下面針對(duì)2色、16色、256色位圖和真彩色位圖分別介紹。對(duì)于2色位圖,用1位就可以表示該象素的顏色(一般0表示黑,1表示白),所以一個(gè)字節(jié)可以表示8個(gè)象素。對(duì)于16色位圖,用4位可以表示一個(gè)象素的顏色,所以一個(gè)字節(jié)可以表示2個(gè)象素。對(duì)于256色位圖,一個(gè)字節(jié)剛好可以表示1個(gè)象素。對(duì)于真彩色圖,三個(gè)字節(jié)才能表示1個(gè)象素,哇,好費(fèi)空間呀!沒(méi)辦法,誰(shuí)叫你想讓圖的顏色顯得更亮麗呢,有得必有失嘛。要注意兩點(diǎn):(1)每一行的字節(jié)數(shù)必須是4的整倍數(shù),如果不是,則需要補(bǔ)齊。這在前面介紹biSizeImage時(shí)已經(jīng)提到了。(2)一般來(lái)說(shuō),.bMP文件的數(shù)據(jù)從下到上,從左到右的。也就是說(shuō),從文件中最先讀到的是圖象最下面一行的左邊第一個(gè)象素,然后是左邊第二個(gè)象素……接下來(lái)是倒數(shù)第二行左邊第一個(gè)象素,左邊第二個(gè)象素……依次類推,最后得到的是最上面一行的最右一個(gè)象素。下面的函數(shù)將pBuffer指向的內(nèi)存塊中的位圖數(shù)據(jù)寫入文件中,lBufferLen參數(shù)為pBuffer指向的內(nèi)存塊的大小,注意必須先指定位圖的BITMAPFILEHEADER結(jié)構(gòu)和BITMAPINFOHEADER結(jié)構(gòu)。STDMETHODIMPCSampleGrabberCallback::BufferCB(doubletime,BYTE*pBuffer,longlBufferLen){if(!g_bSnap)returnE_FAIL;BOOLbWrite=FALSE;HANDLEhFile=CreateFile("E:\\Test.bmp",GENERIC_WRITE,FILE_SHARE_READ,NULL,CREATE_ALWAYS,NULL,NULL);if(hFile==INVALID_HANDLE_VALUE){returnE_FAIL;}//首先初始化位圖文件頭結(jié)構(gòu)(BITMAPFILEHEADER),并將其寫入文件。BITMAPFILEHEADERbmpFileHeader;//memset(&bmpFileHeader,0,sizeof(bmpFileHeader));ZeroMemory(&bmpFileHeader,sizeof(bmpFileHeader));bmpFileHeader.bfType='MB';bmpFileHeader.bfSize=sizeof(bmpFileHeader)+lBufferLen+sizeof(BITMAPINFOHEADER);bmpFileHeader.bfOffBits=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER);DWORDdwWritten=0;bWrite=WriteFile(hFile,&bmpFileHeader,sizeof(bmpFileHeader),&dwWritten,NULL);if(!bWrite){MessageBox(0,TEXT("failtowrite"),TEXT("Error"),MB_OK);}//初始化BITMAPINFOHEADER結(jié)構(gòu)并將其寫入文件。//VIDEOINFOHEADER*viInfoHeader=(VIDEOINFOHEADER*)g_media_type.pbFormat;//FreeMediaType(g_media_type);BITMAPINFOHEADERbmpInfoHeader;ZeroMemory(&bmpInfoHeader,sizeof(bmpInfoHeader));//memset(&bmpInfoHeader,0,sizeof(bmpInfoHeader));bmpInfoHeader.biSize=sizeof(bmpInfoHeader);bmpInfoHeader.biWidth=lWidth;bmpInfoHeader.biHeight=lHeight;bmpInfoHeader.biPlanes=1;bmpInfoHeader.biBitCount=16;//???248dwWritten=0;bWrite=WriteFile(hFile,&bmpInfoHeader,sizeof(bmpInfoHeader),&dwWritten,NULL);if(!bWrite){MessageBox(0,TEXT("failtowrite"),TEXT("Error"),MB_OK);}//最后將位圖的主要數(shù)據(jù)寫入文件。dwWritten=0;bWrite=WriteFile(hFile,pBuffer,lBufferLen,&dwWritten,NULL);if(!bWrite){MessageBox(0,TEXT("failtowrite"),TEXT("Error"),MB_OK);}CloseHandle(hFile);CWnd*pMainWnd=theApp.GetMainWnd();CDfgDlg*pDfg=(CDfgDlg*)pMainWnd;HWNDhwnd=pDfg->m_picture.GetSafeHwnd();RECTrc;::GetWindowRect(hwnd,&rc);longlStillWidth=rc.right-rc.left;longlStillHeight=rc.bottom-rc.top;HDChdcStill=GetDC(hwnd);PAINTSTRUCTps;BeginPaint(hwnd,&ps);SetStretchBltMode(hdcStill,COLORONCOLOR);StretchDIBits(hdcStill,0,0,lStillWidth,lStillHeight,0,0,lWidth,lHeight,pBuffer,(BITMAPINFO*)&bmpInfoHeader,DIB_RGB_COLORS,SRCCOPY);EndPaint(hwnd,&ps);ReleaseDC(hwnd,hdcStill);g_bSnap=!g_bSnap;returnS_OK;}關(guān)于CreateDIBSection函數(shù):HBITMAPCreateDIBSection(HDChdc, //handletoDCCONSTBITMAPINFO*pbmi, //bitmapdataUINTiUsage, //datatypeindicatorVOID**ppvBits, //bitvaluesHANDLEhSection, //handletofilemappingobjectDWORDdwOffset //offsettobitmapbitvalues);CreateDIBSection函數(shù)會(huì)根據(jù)位圖結(jié)構(gòu)信息(pbmi)分配內(nèi)存空間,你不用為它分配內(nèi)存,這塊內(nèi)存也不需要你釋放,系統(tǒng)會(huì)自己釋放的。
然后將位圖中的圖像數(shù)據(jù)讀入這個(gè)內(nèi)存地址,顯示即可。
LPBYTElpBits;HBITMAPhBmp=::CreateDIBSection(dcMem.m_hDC,lpBitmap,DIB_PAL_COLORS,&lpBits,NULL,0);//將圖像數(shù)據(jù)填充到得到的內(nèi)存地址中
file.ReadHuge(lpBits,dwBitlen);
pDC->StretchBlt(0,0,bmp.bmWidth,bmp.bmHeight,&dcMem,0,0,bmp.bmWidth,bmp.bmHeight,SRCCOPY);首先讓我們檢查一下如何簡(jiǎn)化CreateDIBSection,并正確地使用它。首先,把最後兩個(gè)參數(shù)hSection和dwOffset,分別設(shè)定為NULL和0,我將在本章最後討論這些參數(shù)的用法。第二,僅在fColorUse參數(shù)設(shè)定為DIB_PAL_COLORS時(shí),才使用hdc參數(shù),如果fColorUse為DIB_RGB_COLORS(或0),hdc將被忽略(這與CreateDIBitmap不同,hdc參數(shù)用於取得與DDB相容的設(shè)備的色彩格式,CreateDIBitmap創(chuàng)建的是DDB(設(shè)備相關(guān)位圖,CreateDIBSection創(chuàng)建設(shè)備無(wú)關(guān)位圖),因此必須指定與位圖所關(guān)聯(lián)的設(shè)備,即hdc,位圖根據(jù)hdc所代表的設(shè)備來(lái)取得位圖的色彩格式)。因此,CreateDIBSection最簡(jiǎn)單的形式僅需要第二和第四個(gè)參數(shù)。第二個(gè)參數(shù)是指向BITMAPINFO結(jié)構(gòu)的指標(biāo),BITMAPINFOHEADER bmih;
BYTE *pBits;
HBITMAPhBitmap;
現(xiàn)在初始化BITMAPINFOHEADER結(jié)構(gòu)的欄位
bmih->biSize=sizeof(BITMAPINFOHEADER);
bmih->biWidth=384;
bmih->biHeight=256;
bmih->biPlanes=1;
bmih->biBitCount=24;
bmih->biCompression=BI_RGB;
bmih->biSizeImage=0;
bmih->biXPelsPerMeter=0;
bmih->biYPelsPerMeter=0;
bmih->biClrUsed=0;
bmih->biClrImportant=0;
在基本準(zhǔn)備後,我們呼叫該函式:
hBitmap=CreateDIBSection(NULL,(BITMAPINFO*)&bmih,0,&pBits,NULL,0);這是函式呼叫所做的:CreateDIBSection檢查BITMAPINFOHEADER結(jié)構(gòu)并配置足夠的記憶體塊來(lái)載入DIB圖素位元。(在這個(gè)例子里,記憶體塊的大小為384×256×3位元組。)它在您提供的pBits參數(shù)中儲(chǔ)存了指向此記憶體塊的指標(biāo)。然而,我們還沒(méi)有做完,點(diǎn)陣圖圖素是未初始化的。如果正在讀取DIB檔案,可以簡(jiǎn)單地把pBits參數(shù)傳遞給ReadFile函式并讀取它們?;蛘呖梢允褂靡恍┏淌酱a「人工」設(shè)定。注意:使用CreateDIBSection函數(shù)獲得的內(nèi)存塊指針(輸出的第四個(gè)參數(shù))所指向的地址中是沒(méi)有內(nèi)容的,我們必須向里面寫入圖像數(shù)據(jù),然后才能夠顯示圖像。位圖數(shù)據(jù)這部分逐個(gè)像素表示圖像。像素是從下到上、從左到右保存的。每個(gè)像素使用一個(gè)或者多個(gè)字節(jié)表示。如果一個(gè)圖像水平線的字節(jié)數(shù)不是4的倍數(shù),這行就使用空字節(jié)補(bǔ)齊,通常是ASCII碼0。範(fàn)例:有一張5*5的圖片,應(yīng)該會(huì)有25個(gè)pixels,但是因?yàn)?不是4的倍數(shù)所以會(huì)顯示成:@@@@@@xxxxx000xxxxx000xxxxx000xxxxx000xxxxx000x代表調(diào)色盤的編號(hào)0代表Null_character@代表調(diào)色盤最後幾筆資料有一張4*4的圖片,應(yīng)該會(huì)有16個(gè)pixels,但是因?yàn)槭?的倍數(shù)所以會(huì)顯示成:@@@@@@xxxxxxxxxxXxxxxxBMP(Bitmap_File)圖形文件是Windows采用的圖形文件格式,在Windows環(huán)境下運(yùn)行的所有圖像處理軟件都支持BMP圖像文件格式。Windows系統(tǒng)內(nèi)部圖像繪制操作都是以BMP為基礎(chǔ)的。Windows3.0以前的BMP文件格式與顯示設(shè)備有關(guān),因此把這種BMP圖像文件格式成為設(shè)備相關(guān)位圖DDB(device-dependentbitmap)文件格式。Windows3.0以后的BMP圖像文件與顯示設(shè)備無(wú)關(guān),因此把這種BMP圖像文件格式稱為設(shè)備無(wú)關(guān)位圖DIB(device-independentbitmap)格式,目的是為了讓W(xué)indows能夠在任何類型的顯示設(shè)備上顯示所存儲(chǔ)的圖像。BMP位圖文件默認(rèn)的文件擴(kuò)展名為BMP或者bmp(有時(shí)它也會(huì)以.DIB或者.RLE作為擴(kuò)展名)。文件結(jié)構(gòu):位圖文件可看成有4個(gè)部分組成:位圖文件頭(bitmap-fileheader),位圖信息頭(bitmap-informationheader),彩色表(colortable)和定義位圖的字節(jié)陣列。1.位圖文件頭:包含信息:文件類型,文件大小,存放位置等信息。C中定義為如下結(jié)構(gòu)體:
typedefstructtagBITMAPFILEHEADER{
UINTbfType;//說(shuō)明文件的類型必須是‘BM’。
DWORDbfSize;//說(shuō)明文件的大小,用字節(jié)為單位
UINTbfReserved1;//保留,但必須為0
UINTbfReserved2;//保留,但必須為0
DWORDbfOffBits;//說(shuō)明從文件頭開始到實(shí)際的圖像數(shù)據(jù)之間的字節(jié)的偏移量。這個(gè)參數(shù)是非常有用的,因?yàn)槲粓D信息頭和調(diào)色板的長(zhǎng)度會(huì)根據(jù)不同情況而變化,所以你可以用這個(gè)偏移值迅速的從文件中讀取到數(shù)據(jù)位。
}BITMAPFILEHEADER;2.位圖信息頭:位圖信息頭(BITMAPINFO)包含位圖信息頭(BITMAPINFOHEADER)和彩色表(RGBQUAD)TypedefstructtagBITMAPINFO{BITMAPINFOHEADERbmiHeader;//包含了有關(guān)位圖的尺寸及位圖格式等信息RGBQUADbmiColors[1];//包含索引圖像的真實(shí)RGB值。}BITMAPINFO;TypedefstructtagBITMAPINFOHEADER{DWORDbiSize;//說(shuō)明BITMAPINFOHEADER結(jié)構(gòu)所需要的字?jǐn)?shù)。LONGbiWidth;//說(shuō)明圖像的寬度,以像素為單位LONGbiHeight;//說(shuō)明像素的高度,以像素為單位WORDbiPlanes;//為目標(biāo)設(shè)備說(shuō)明位面數(shù),其值將總是被設(shè)為1WORDbiBitCount;//說(shuō)明比特?cái)?shù)/像素,其值為1,4,8,16,24,32DWORDbiCompression;//說(shuō)明壓縮方式DWORDbiSizeImage;//說(shuō)明圖像大小,以字節(jié)為單位LONGbiXPelsPerMeter;//說(shuō)明水平分辨率,用象素/米LONGbiYPelsPerMeter;//說(shuō)明垂直分辨率,用象素/米DWORDbiClrUsed;//說(shuō)明位圖實(shí)際使用的彩色表中的顏色索引數(shù)DWORDbiClrImportant;//說(shuō)明對(duì)圖像顯示有重要影響的顏色索引的數(shù)目,如果是0,表示都重要。}BITMAPINFOHEADER;現(xiàn)就BITMAPINFOHEADER結(jié)構(gòu)作如下說(shuō)明:(1)彩色表的定位應(yīng)用程序可使用存儲(chǔ)在biSize成員中的信息來(lái)查找在BITMAPINFO結(jié)構(gòu)中的彩色表,如下所示:pColor=((LPSTR)pBitmapInfo(WORD)(pBitmapInfo->bmiHeader.biSize))(2)biBitCountbiBitCount=1表示位圖最多有兩種顏色,缺省情況下是黑色和白色,你也可以自己定義這兩種顏色。圖像信息頭裝調(diào)色板中將有兩個(gè)調(diào)色板項(xiàng),稱為索引0和索引1。圖象數(shù)據(jù)陣列中的每一位表示一個(gè)象素。如果一個(gè)位是0,顯示時(shí)就使用索引0的RGB值,如果位是1,則使用索引1的RGB值。biBitCount=4表示位圖最多有16種顏色。每個(gè)象素用4位表示,并用這4位作為彩色表的表項(xiàng)來(lái)查找該象素的顏色。例如,如果位圖中的第一個(gè)字節(jié)為0x1F,它表示有兩個(gè)象素,第一象素的顏色就在彩色表的第2表項(xiàng)中查找,而第二個(gè)象素的顏色就在彩色表的第16表項(xiàng)中查找。此時(shí),調(diào)色板中缺省情況下會(huì)有16個(gè)RGB項(xiàng)。對(duì)應(yīng)于索引0到索引15。biBitCount=8表示位圖最多有256種顏色。每個(gè)象素用8位表示,并用這8位作為彩色表的表項(xiàng)來(lái)查找該象素的顏色。例如,如果位圖中的第一個(gè)字節(jié)為0x1F,這個(gè)象素的顏色就在彩色表的第32表項(xiàng)中查找。此時(shí),缺省情況下,調(diào)色板中會(huì)有256個(gè)RGB項(xiàng),對(duì)應(yīng)于索引0到索引255。biBitCount=16表示位圖最多有216種顏色。每個(gè)色素用16位(2個(gè)字節(jié))表示。這種格式叫作高彩色,或叫增強(qiáng)型16位色,或64K色。它的情況比較復(fù)雜,當(dāng)biCompression成員的值是BI_RGB時(shí),它沒(méi)有調(diào)色板。16位中,最低的5位表示藍(lán)色分量,中間的5位表示綠色分量,高的5位表示紅色分量,一共占用了15位,最高的一位保留,設(shè)為0。這種格式也被稱作55516位位圖。如果biCompression成員的值是BI_BITFIELDS,那么情況就復(fù)雜了,首先是原來(lái)調(diào)色板的位置被三個(gè)DWORD變量占據(jù),稱為紅、綠、藍(lán)掩碼。分別用于描述紅、綠、藍(lán)分量在16位中所占的位置。在Windows95(或98)中,系統(tǒng)可接受兩種格式的位域:555和565,在555格式下,紅、綠、藍(lán)的掩碼分別是:0x7C00、0x03E0、0x001F,而在565格式下,它們則分別為:0xF800、0x07E0、0x001F。你在讀取一個(gè)像素之后,可以分別用掩碼“與”上像素值,從而提取出想要的顏色分量(當(dāng)然還要再經(jīng)過(guò)適當(dāng)?shù)淖笥乙撇僮鳎T贜T系統(tǒng)中,則沒(méi)有格式限制,只不過(guò)要求掩碼之間不能有重疊。(注:這種格式的圖像使用起來(lái)是比較麻煩的,不過(guò)因?yàn)樗娘@示效果接近于真彩,而圖像數(shù)據(jù)又比真彩圖像小的多,所以,它更多的被用于游戲軟件)。biBitCount=24表示位圖最多有224種顏色。這種位圖沒(méi)有調(diào)色板(bmiColors成員尺寸為0),在位數(shù)組中,每3個(gè)字節(jié)代表一個(gè)象素,分別對(duì)應(yīng)于顏色R、G、B。biBitCount=32表示位圖最多有232種顏色。這種位圖的結(jié)構(gòu)與16位位圖結(jié)構(gòu)非常類似,當(dāng)biCompression成員的值是BI_RGB時(shí),它也沒(méi)有調(diào)色板,32位中有24位用于存放RGB值,順序是:最高位—保留,紅8位、綠8位、藍(lán)8位。這種格式也被成為88832位圖。如果biCompression成員的值是BI_BITFIELDS時(shí),原來(lái)調(diào)色板的位置將被三個(gè)DWORD變量占據(jù),成為紅、綠、藍(lán)掩碼,分別用于描述紅、綠、藍(lán)分量在32位中所占的位置。在Windows95(or98)中,系統(tǒng)只接受888格式,也就是說(shuō)三個(gè)掩碼的值將只能是:0xFF0000、0xFF00、0xFF。而在NT系統(tǒng)中,你只要注意使掩碼之間不產(chǎn)生重疊就行。(注:這種圖像格式比較規(guī)整,因?yàn)樗荄WORD對(duì)齊的,所以在內(nèi)存中進(jìn)行圖像處理時(shí)可進(jìn)行匯編級(jí)的代碼優(yōu)化(簡(jiǎn)單))。(3)ClrUsedBITMAPINFOHEADER結(jié)構(gòu)中的成員ClrUsed指定實(shí)際使用的顏色數(shù)目。如果ClrUsed設(shè)置成0,位圖使用的顏色數(shù)目就等于biBitCount成員中的數(shù)目。請(qǐng)注意,如果ClrUsed的值不是可用顏色的最大值或不是0,則在編程時(shí)應(yīng)該注意調(diào)色板尺寸的計(jì)算,比如在4位位圖中,調(diào)色板的缺省尺寸應(yīng)該是16*sizeof(RGBQUAD),但是,如果ClrUsed的值不是16或者不是0,那么調(diào)色板的尺寸就應(yīng)該是ClrUsed*sizeof(RGBQUAD)。(4)圖象數(shù)據(jù)壓縮①BI_RLE8:每個(gè)象素為8比特的RLE壓縮編碼,可使用編碼方式和絕對(duì)方式中的任何一種進(jìn)行壓縮,這兩種方式可在同一幅圖中的任何地方使用。編碼方式:由2個(gè)字節(jié)組成,第一個(gè)字節(jié)指定使用相同顏色的象素?cái)?shù)目,第二個(gè)字節(jié)指定使用的顏色索引。此外,這個(gè)字節(jié)對(duì)中的第一個(gè)字節(jié)可設(shè)置為0,聯(lián)合使用第二個(gè)字節(jié)的值表示:第二個(gè)字節(jié)的值為0:行的結(jié)束。
第二個(gè)字節(jié)的值為1:圖象結(jié)束。
第二個(gè)字節(jié)的值為2:其后的兩個(gè)字節(jié)表示下一個(gè)象素從當(dāng)前開始的水平和垂直位置的偏移量。
絕對(duì)方式:第一個(gè)字節(jié)設(shè)置為0,而第二個(gè)字節(jié)設(shè)置為0x03~0xFF之間的一個(gè)值。在這種方式中,第二個(gè)字節(jié)表示跟在這個(gè)字節(jié)后面的字節(jié)數(shù),每個(gè)字節(jié)包含單個(gè)象素的顏色索引。壓縮數(shù)據(jù)格式需要字邊界(wordboundary)對(duì)齊。下面的例子是用16進(jìn)制表示的8-位壓縮圖象數(shù)據(jù):0304050600034556670002780002050102780000091E0001
這些壓縮數(shù)據(jù)可解釋為:壓縮數(shù)據(jù)擴(kuò)展數(shù)據(jù)0304040404050606060606060003455667004556670278787800020501從當(dāng)前位置右移5個(gè)位置后向下移一行027878780000行結(jié)束091E1E1E1E1E1E1E1E1E1E0001RLE編碼圖象結(jié)束②BI_RLE4:每個(gè)象素為4比特的RLE壓縮編碼,同樣也可使用編碼方式和絕對(duì)方式中的任何一種進(jìn)行壓縮,這兩種方式也可在同一幅圖中的任何地方使用。這兩種方式是:編碼方式:由2個(gè)字節(jié)組成,第一個(gè)字節(jié)指定象素?cái)?shù)目,第二個(gè)字節(jié)包含兩種顏色索引,一個(gè)在高4位,另一個(gè)在低4位。第一個(gè)象素使用高4位的顏色索引,第二個(gè)使用低4位的顏色索引,第3個(gè)使用高4位的顏色索引,依此類推。絕對(duì)方式:這個(gè)字節(jié)對(duì)中的第一個(gè)字節(jié)設(shè)置為0,第二個(gè)字節(jié)包含有顏色索引數(shù),其后續(xù)字節(jié)包含有顏色索引,顏色索引存放在該字節(jié)的高、低4位中,一個(gè)顏色索引對(duì)應(yīng)一個(gè)象素。此外,BI_RLE4也同樣聯(lián)合使用第二個(gè)字節(jié)中的值表示:第二個(gè)字節(jié)的值為0:行的結(jié)束。
第二個(gè)字節(jié)的值為1:圖象結(jié)束。
第二個(gè)字節(jié)的值為2:其后的兩個(gè)字節(jié)表示下一個(gè)象素從當(dāng)前開始的水平和垂直位置的偏移量。
下面的例子是用16進(jìn)制數(shù)表示的4-位壓縮圖象數(shù)據(jù):0304050600064556670004780002050104780000091E0001這些壓縮數(shù)據(jù)可解釋為:壓縮數(shù)據(jù)擴(kuò)展數(shù)據(jù)03040400506060600006455667004556670478787800020501從當(dāng)前位置右移5個(gè)位置后向下移一行047878780000行結(jié)束091E1E1E1E1E10001RLE圖象結(jié)束彩色表:彩色表包含的元素與位圖所具有的顏色數(shù)相同。typedefstructtagRGBQUAD{/*rgbq*/BYTErgbBlue;
BYTErgbGreen;
BYTErgbRed;
BYTErgbReserved;}RGBQUAD;位圖數(shù)據(jù)長(zhǎng)度由圖像尺寸,象素位數(shù),壓縮方式等共同決定.由于存儲(chǔ)要求,圖像的列數(shù)必須為4的整數(shù)倍BMP文件的數(shù)據(jù)格式可以分為兩大類:使用顏色表型和直接數(shù)據(jù)區(qū)型biBitCount值為1,4,8時(shí)數(shù)據(jù)區(qū)存放顏色索引,24時(shí)為直接數(shù)據(jù)一,文件格式定義:
BMP(Bitmap-File)圖形文件是Windows采用的圖形文件格式,在Windows環(huán)境下運(yùn)行的所有圖象處理軟件都支持BMP圖像文件格式。Windows系統(tǒng)內(nèi)部各圖像繪制操作都是以BMP為基礎(chǔ)的。Windows3.0以前的BMP圖文件格式與顯示設(shè)備有關(guān),因此把這種BMP圖像文件格式稱為設(shè)備相關(guān)位圖DDB(device-dependentbitmap)文件格式。Windows3.0以后的BMP圖像文件與顯示設(shè)備無(wú)關(guān),因此把這種BMP圖像文件格式稱為設(shè)備無(wú)關(guān)位圖DIB(device-independentbitmap)格式(注:Windows3.0以后,在系統(tǒng)中仍然存在DDB位圖,像BitBlt()這種函數(shù)就是基于DDB位圖的,只不過(guò)如果你想將圖像以BMP格式保存到磁盤文件中時(shí),微軟極力推薦你以DIB格式保存),目的是為了讓W(xué)indows能夠在任何類型的顯示設(shè)備上顯示所存儲(chǔ)的圖像。BMP位圖文件默認(rèn)的文件擴(kuò)展名是BMP或者bmp(有時(shí)它也會(huì)以.DIB或.RLE作擴(kuò)展名)。
文件結(jié)構(gòu)
位圖文件可看成由4個(gè)部分組成:位圖文件頭(bitmap-fileheader)、位圖信息頭(bitmap-informationheader)、彩色表(colortable)和定義位圖的字節(jié)陣列,它具有如下所示的形式。
位圖文件的組成結(jié)構(gòu)名稱符號(hào)
位圖文件頭(bitmap-fileheader)BITMAPFILEHEADERbmfh
位圖信息頭(bitmap-informationheader)BITMAPINFOHEADERbmih
彩色表(colortable)RGBQUADaColors[]
圖像數(shù)據(jù)陣列字節(jié)BYTEaBitmapBits[]
位圖文件結(jié)構(gòu)可綜合在表6-01中。
表01位圖文件結(jié)構(gòu)內(nèi)容摘要
偏移量域的名稱大小內(nèi)容
圖象文件
頭0000h文件標(biāo)識(shí)2bytes兩字節(jié)的內(nèi)容用來(lái)識(shí)別位圖的類型:
‘BM’:Windows3.1x,95,NT,…
‘BA’:OS/2BitmapArray
‘CI’:OS/2ColorIcon
‘CP’:OS/2ColorPointer
‘IC’:OS/2Icon
‘PT’:OS/2Pointer
注:因?yàn)镺S/2系統(tǒng)并沒(méi)有被普及開,所以在編程時(shí),你只需判斷第一個(gè)標(biāo)識(shí)“BM”就行。
0002hFileSize1dword用字節(jié)表示的整個(gè)文件的大小
0006hReserved1dword保留,必須設(shè)置為0
000AhBitmapDataOffset1dword從文件開始到位圖數(shù)據(jù)開始之間的數(shù)據(jù)(bitmapdata)之間的偏移量
000EhBitmapHeaderSize1dword位圖信息頭(BitmapInfoHeader)的長(zhǎng)度,用來(lái)描述位圖的顏色、壓縮方法等。下面的長(zhǎng)度表示:
28h-Windows3.1x,95,NT,…
0Ch-OS/21.x
F0h-OS/22.x
注:在Windows95、98、2000等操作系統(tǒng)中,位圖信息頭的長(zhǎng)度并不一定是28h,因?yàn)槲④浺呀?jīng)制定出了新的BMP文件格式,其中的信息頭結(jié)構(gòu)變化比較大,長(zhǎng)度加長(zhǎng)。所以最好不要直接使用常數(shù)28h,而是應(yīng)該從具體的文件中讀取這個(gè)值。這樣才能確保程序的兼容性。
0012hWidth1dword位圖的寬度,以象素為單位
0016hHeight1dword位圖的高度,以象素為單位
001AhPlanes1word位圖的位面數(shù)(注:該值將總是1)
圖像信息頭
001ChBitsPerPixel1word每個(gè)象素的位數(shù)
1-單色位圖(實(shí)際上可有兩種顏色,缺省情況下是黑色和白色。你可以自己定義這兩種顏色)
4-16色位圖
8-256色位圖
16-16bit高彩色位圖
24-24bit真彩色位圖
32-32bit增強(qiáng)型真彩色位圖
001EhCompression1dword壓縮說(shuō)明:
0-不壓縮(使用BI_RGB表示)
1-RLE8-使用8位RLE壓縮方式(用BI_RLE8表示)
2-RLE4-使用4位RLE壓縮方式(用BI_RLE4表示)
3-Bitfields-位域存放方式(用BI_BITFIELDS表示)
0022hBitmapDataSize1dword用字節(jié)數(shù)表示的位圖數(shù)據(jù)的大小。該數(shù)必須是4的倍數(shù)
0026hHResolution1dword用象素/米表示的水平分辨率
002AhVResolution1dword用象素/米表示的垂直分辨率
002EhColors1dword位圖使用的顏色數(shù)。如8-比特/象素表示為100h或者256.
0032hImportantColors1dword指定重要的顏色數(shù)。當(dāng)該域的值等于顏色數(shù)時(shí)(或者等于0時(shí)),表示所有顏色都一樣重要
調(diào)色板數(shù)據(jù)根據(jù)BMP版本的不同而不同PaletteN*4byte調(diào)色板規(guī)范。對(duì)于調(diào)色板中的每個(gè)表項(xiàng),這4個(gè)字節(jié)用下述方法來(lái)描述RGB的值:
1字節(jié)用于藍(lán)色分量
1字節(jié)用于綠色分量
1字節(jié)用于紅色分量
1字節(jié)用于填充符(設(shè)置為0)
圖像數(shù)據(jù)根據(jù)BMP版本及調(diào)色板尺寸的不同而不同BitmapDataxxxbytes該域的大小取決于壓縮方法及圖像的尺寸和圖像的位深度,它包含所有的位圖數(shù)據(jù)字節(jié),這些數(shù)據(jù)可能是彩色調(diào)色板的索引號(hào),也可能是實(shí)際的RGB值,這將根據(jù)圖像信息頭中的位深度值來(lái)決定。
構(gòu)件詳解
1.位圖文件頭
位圖文件頭包含有關(guān)于文件類型、文件大小、存放位置等信息,在Windows3.0以上版本的位圖文件中用BITMAPFILEHEADER結(jié)構(gòu)來(lái)定義:
typedefstructtagBITMAPFILEHEADER{/*bmfh*/
UINTbfType;
DWORDbfSize;
UINTbfReserved1;
UINTbfReserved2;
DWORDbfOffBits;
}BITMAPFILEHEADER;
其中:
bfType說(shuō)明文件的類型.(該值必需是0x4D42,也就是字符'BM'。我們不需要判斷OS/2的位圖標(biāo)識(shí),這么做現(xiàn)在來(lái)看似乎已經(jīng)沒(méi)有什么意義了,而且如果要支持OS/2的位圖,程序?qū)⒆兊煤芊爆崱K?,在此只建議你檢察'BM'標(biāo)識(shí))
bfSize說(shuō)明文件的大小,用字節(jié)為單位
bfReserved1保留,必須設(shè)置為0
bfReserved2保留,必須設(shè)置為0
bfOffBits說(shuō)明從文件頭開始到實(shí)際的圖像數(shù)據(jù)之間的字節(jié)的偏移量。這個(gè)參數(shù)是非常有用的,因?yàn)槲粓D信息頭和調(diào)色板的長(zhǎng)度會(huì)根據(jù)不同情況而變化,所以你可以用這個(gè)偏移值迅速的從文件中讀取到位數(shù)據(jù)。
2.位圖信息頭
位圖信息用BITMAPINFO結(jié)構(gòu)來(lái)定義,它由位圖信息頭(bitmap-informationheader)和彩色表(colortable)組成,前者用BITMAPINFOHEADER結(jié)構(gòu)定義,后者用RGBQUAD結(jié)構(gòu)定義。BITMAPINFO結(jié)構(gòu)具有如下形式:
typedefstructtagBITMAPINFO{/*bmi*/
BITMAPINFOHEADERbmiHeader;
RGBQUADbmiColors[1];
}BITMAPINFO;
其中:bmiHeader說(shuō)明BITMAPINFOHEADER結(jié)構(gòu),其中包含了有關(guān)位圖的尺寸及位格式等信息
bmiColors說(shuō)明彩色表RGBQUAD結(jié)構(gòu)的陣列,其中包含索引圖像的真實(shí)RGB值。
BITMAPINFOHEADER結(jié)構(gòu)包含有位圖文件的大小、壓縮類型和顏色格式,其結(jié)構(gòu)定義為:
typedefstructtagBITMAPINFOHEADER{/*bmih*/
DWORDbiSize;
LONGbiWidth;
LONGbiHeight;
WORDbiPlanes;
WORDbiBitCount;
DWORDbiCompression;
DWORDbiSizeImage;
LONGbiXPelsPerMeter;
LONGbiYPelsPerMeter;
DWORDbiClrUsed;
DWORDbiClrImportant;
}BITMAPINFOHEADER;
其中:
biSize說(shuō)明BITMAPINFOHEADER結(jié)構(gòu)所需要的字?jǐn)?shù)。注:這個(gè)值并不一定是BITMAPINFOHEADER結(jié)構(gòu)的尺寸,它也可能是sizeof(BITMAPV4HEADER)的值,或是sizeof(BITMAPV5HEADER)的值。這要根據(jù)該位圖文件的格式版本來(lái)決定,不過(guò),就現(xiàn)在的情況來(lái)看,絕大多數(shù)的BMP圖像都是BITMAPINFOHEADER結(jié)構(gòu)的。biWidth說(shuō)明圖像的寬度,以象素為單位;biHeight說(shuō)明圖像的高度,以象素為單位。注:這個(gè)值除了用于描述圖像的高度之外,它還有另一個(gè)用處,就是指明該圖像是倒向的位圖,還是正向的位圖。如果該值是一個(gè)正數(shù),說(shuō)明圖像是倒向的,如果該值是一個(gè)負(fù)數(shù),則說(shuō)明圖像是正向的。大多數(shù)的BMP文件都是倒向的位圖,也就是,高度值是一個(gè)正數(shù)。(注:當(dāng)高度值是一個(gè)負(fù)數(shù)時(shí)(正向圖像),圖像將不能被壓縮(也就是說(shuō)biCompression成員將不能是BI_RLE8或BI_RLE4)。
biPlanes為目標(biāo)設(shè)備說(shuō)明位面數(shù),其值將總是被設(shè)為1
biBitCount說(shuō)明比特?cái)?shù)/象素,其值為1、4、8、16、24、或32
biCompression說(shuō)明圖像數(shù)據(jù)壓縮的類型。其值可以是下述值之一:
BI_RGB:沒(méi)有壓縮;
BI_RLE8:每個(gè)象素8比特的RLE壓縮編碼,壓縮格式由2字節(jié)組成(重復(fù)象素計(jì)數(shù)和顏色索引);
BI_RLE4:每個(gè)象素4比特的RLE壓縮編碼,壓縮格式由2字節(jié)組成
BI_BITFIELDS:每個(gè)象素的比特由指定的掩碼決定。
biSizeImage說(shuō)明圖象的大小,以字節(jié)為單位。當(dāng)用BI_RGB格式時(shí),可設(shè)置為0
biXPelsPerMeter說(shuō)明水平分辨率,用象素/米表示
biYPelsPerMeter說(shuō)明垂直分辨率,用象素/米表示
biClrUsed說(shuō)明位圖實(shí)際使用的彩色表中的顏色索引數(shù)(設(shè)為0的話,則說(shuō)明使用所有調(diào)色板項(xiàng))
biClrImportant說(shuō)明對(duì)圖象顯示有重要影響的顏色索引的數(shù)目,如果是0,表示都重要。
現(xiàn)就BITMAPINFOHEADER結(jié)構(gòu)作如下說(shuō)明:
(1)彩色表的定位
應(yīng)用程序可使用存儲(chǔ)在biSize成員中的信息來(lái)查找在BITMAPINFO結(jié)構(gòu)中的彩色表,如下所示:
pColor=((LPSTR)pBitmapInfo+(WORD)(pBitmapInfo->bmiHeader.biSize))
(2)biBitCount
biBitCount=1表示位圖最多有兩種顏色,缺省情況下是黑色和白色,你也可以自己定義這兩種顏色。圖像信息頭裝調(diào)色板中將有兩個(gè)調(diào)色板項(xiàng),稱為索引0和索引1。圖像數(shù)據(jù)陣列中的每一位表示一個(gè)象素。如果一個(gè)位是0,顯示時(shí)就使用索引0的RGB值,如果位是1,則使用索引1的RGB值。
biBitCount=4表示位圖最多有16(24)種顏色。每個(gè)象素用4位表示,并用這4位作為彩色表的表項(xiàng)來(lái)查找該象素的顏色。例如,如果位圖中的第一個(gè)字節(jié)為0x1F,它表示有兩個(gè)象素,第一象素的顏色就在彩色表的第2表項(xiàng)中查找,而第二個(gè)象素的顏色就在彩色表的第16表項(xiàng)中查找。此時(shí),調(diào)色板中缺省情況下會(huì)有16個(gè)RGB項(xiàng)。對(duì)應(yīng)于索引0到索引15。
biBitCount=8表示位圖最多有256種顏色。每個(gè)象素用8位表示,并用這8位作為彩色表的表項(xiàng)來(lái)查找該象素的顏色。例如,如果位圖中的第一個(gè)字節(jié)為0x1F,這個(gè)象素的顏色就在彩色表的第32表項(xiàng)中查找。此時(shí),缺省情況下,調(diào)色板中會(huì)有256個(gè)RGB項(xiàng),對(duì)應(yīng)于索引0到索引255。
biBitCount=16表示位圖最多有216種顏色。每個(gè)色素用16位(2個(gè)字節(jié))表示。這種格式叫作高彩色,或叫增強(qiáng)型16位色,或6
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025-2030消防安全設(shè)備行業(yè)標(biāo)準(zhǔn)體系完善市場(chǎng)準(zhǔn)入策略分析
- 2025-2030消防員服裝生產(chǎn)企業(yè)市場(chǎng)供需現(xiàn)狀分析評(píng)估方案
- 2025-2030消費(fèi)級(jí)無(wú)人機(jī)適航認(rèn)證體系完善進(jìn)程與市場(chǎng)準(zhǔn)入研究報(bào)告
- 2025-2030消費(fèi)級(jí)AR硬件設(shè)備用戶體驗(yàn)痛點(diǎn)與產(chǎn)品迭代方向研究報(bào)告
- 2025-2030消費(fèi)級(jí)3D打印材料多元化發(fā)展與在線平臺(tái)銷售渠道變革
- 2025-2030浙江省智慧物流體系建設(shè)與現(xiàn)代供應(yīng)鏈優(yōu)化探討
- 2025-2030浙江IT產(chǎn)業(yè)競(jìng)爭(zhēng)現(xiàn)狀分析及數(shù)字化轉(zhuǎn)型發(fā)展研究報(bào)告
- 2025年黑龍江商業(yè)職業(yè)學(xué)院輔導(dǎo)員考試真題
- 會(huì)計(jì)職稱資格測(cè)試試題及答案
- 汽車維修行業(yè)技能培訓(xùn)標(biāo)準(zhǔn)制定
- 攜程推廣模式方案
- THHPA 001-2024 盆底康復(fù)管理質(zhì)量評(píng)價(jià)指標(biāo)體系
- JGT138-2010 建筑玻璃點(diǎn)支承裝置
- 垃圾清運(yùn)服務(wù)投標(biāo)方案(技術(shù)方案)
- 顱鼻眶溝通惡性腫瘤的治療及護(hù)理
- 光速測(cè)量實(shí)驗(yàn)講義
- 斷橋鋁合金門窗施工組織設(shè)計(jì)
- 新蘇教版六年級(jí)科學(xué)上冊(cè)第一單元《物質(zhì)的變化》全部教案
- 四川山體滑坡地質(zhì)勘察報(bào)告
- 工程結(jié)算書(設(shè)備及安裝類)
- GB/T 19142-2016出口商品包裝通則
評(píng)論
0/150
提交評(píng)論