數(shù)字圖象處理計(jì)算機(jī)畢業(yè)論文
《數(shù)字圖象處理計(jì)算機(jī)畢業(yè)論文》由會(huì)員分享,可在線(xiàn)閱讀,更多相關(guān)《數(shù)字圖象處理計(jì)算機(jī)畢業(yè)論文(31頁(yè)珍藏版)》請(qǐng)?jiān)谘b配圖網(wǎng)上搜索。
1、 摘要 圖片的合成和縮放我們實(shí)現(xiàn)了其基本的算法,本文通過(guò)bmp位圖數(shù)據(jù)源,通過(guò)采用雙線(xiàn)形插值,后處理操作和合成算法實(shí)現(xiàn)了對(duì)圖片的基本操作,并以此為基礎(chǔ)實(shí)現(xiàn)了對(duì)bmp位圖的讀寫(xiě)。試驗(yàn)結(jié)果表明,我們所實(shí)現(xiàn)的算法適用于對(duì)BMP位圖文件的基本操作。 在實(shí)現(xiàn)數(shù)字圖象處理的過(guò)程中,主要是通過(guò)對(duì)圖像中的每一個(gè)像素點(diǎn)運(yùn)用各種圖像處理算法來(lái)達(dá)到預(yù)期的效果,所以進(jìn)行圖像處理的第一步,也是我們最關(guān)心的問(wèn)題,是如何得到圖像中每一個(gè)像素點(diǎn)的亮度值;為了觀(guān)察和驗(yàn)證處理的圖像效果,另一個(gè)需要解決的問(wèn)題是如何將處理前后的圖像正確的顯示出來(lái)。我們就是解決這些問(wèn)題。 關(guān)鍵詞:圖片的合成和縮放;雙線(xiàn)形插值;bmp位圖;
2、數(shù)字圖象處理 vc++ picture processing implementation Abstract The picture synthesis we have realized its basic algorithm, this article through the bmp position chart data pool, through used the double linear interpolation, the post-processing operation and the synthesis algorithm has re
3、alized to the picture elementary operation, and has realized read-write to the bmp position chart take this as the foundation. The test result indicated, we realize the algorithm is suitable for to the BMP position chart document elementary operation. In the realization digital image processing pro
4、cess, mainly is through utilizes each kind of picture processing algorithm to in the picture each picture to achieve the anticipated effect, therefore carries on picture processing the first step, also is our most issue of concern, is how obtains in the picture each picture brightness value; In orde
5、r to observe with the confirmation processing picture effect, around another needs to solve how will the question is process the picture correct demonstration. We solve these problems. Key words: Picture synthesis; Double linear interpolation; Bmp position chart; Digital image processing 目 錄
6、1 圖像縮放合成處理的意義國(guó)內(nèi)外的情況綜述…………………………… ……1 2 設(shè)備無(wú)關(guān)位圖文件的讀寫(xiě)存和縮放………………………………………………2 2.1 BMP文件的格式… …………………………………………………………………2 2.1.1 BMP文件組成……………………………………………………………………2 2.1.2 BMP文件頭………………………………………………………………………2 2.1.3 位圖信息頭……………………………………………………………………3 2.1.4 顏色表…………………………………………………………………………3 2.1.5 位圖數(shù)據(jù)……
7、…………………………………………………………………4 2.2 BMP文件的讀寫(xiě)……… ……………………………………………………………4 2.3 BMP文件的保存……… …………………………………………………………10 2.4 BMP文件的縮放…… ……………………………………………………………15 3 圖像合成的具體方法… ……………………………………………………………21 3.1 圖片合成算法詳解…………………………………………………………………21 3.2 圖片合成算法集的實(shí)現(xiàn) …… ……………………………………………………22 3.3 圖片合成檢查步驟……………
8、……………………………………………………24 4 試驗(yàn)數(shù)據(jù)與展望 …… ………………………………………………………………25 4.1試驗(yàn)數(shù)據(jù)…………………… ………………………………………………………25 4.2展望…………………………… ……………………………………………………26 參考文獻(xiàn)……………………………………………………………………………………28 致謝………… ………………………………………………………………………………30 引 言 數(shù)字圖像處理技術(shù)與理論是計(jì)算機(jī)應(yīng)用的一個(gè)重要領(lǐng)域,許多工程應(yīng)用都涉及到圖像處理,一直有一個(gè)強(qiáng)烈的愿望,想系統(tǒng)
9、的寫(xiě)一個(gè)關(guān)于數(shù)字圖像處理的講座,由于工作學(xué)習(xí)很忙,時(shí)至今日才得以實(shí)現(xiàn)。 1 圖片縮放合成的意義,國(guó)內(nèi)外的情況綜述 “圖”是物體透射光或反射光的分布,“像”是人的視覺(jué)系統(tǒng)對(duì)圖的接收在大腦中形成的印象或認(rèn)識(shí)。圖像是兩者的結(jié)合。人類(lèi)獲取外界信息是靠聽(tīng)覺(jué)、視覺(jué)、觸覺(jué)、嗅覺(jué)、味覺(jué)等,但絕大部分(約80%左右)來(lái)自視覺(jué)所接收的圖像信息。圖像處理就是對(duì)圖像信息進(jìn)行加工處理,以滿(mǎn)足人的視覺(jué)心理和實(shí)際應(yīng)用的需要。簡(jiǎn)單的說(shuō),依靠計(jì)算機(jī)對(duì)圖像進(jìn)行各種目的的處理我們就稱(chēng)之為數(shù)字圖像處理。早期的數(shù)字圖像處理的目的是以人為對(duì)象,為了滿(mǎn)足人的視覺(jué)效果而改善圖像的質(zhì)量,處理過(guò)程中輸入的是質(zhì)量差的圖像,輸出的是質(zhì)量好的
10、圖像,常用的圖像處理方法有圖像增強(qiáng)、復(fù)原等。隨著計(jì)算機(jī)技術(shù)的發(fā)展,有一類(lèi)圖像處理是以機(jī)器為對(duì)象,處理的目的是使機(jī)器能夠自動(dòng)識(shí)別目標(biāo),這稱(chēng)之為圖像的識(shí)別,因?yàn)檫@其中要牽涉到一些復(fù)雜的模式識(shí)別的理論,討論其中最基本的內(nèi)容。由于在許多實(shí)際應(yīng)用的編程中往往都要涉及到數(shù)字圖像處理,涉及到圖像合成算法,討論如何利用微軟的Visual C++開(kāi)發(fā)工具來(lái)實(shí)現(xiàn)一些常用的數(shù)字圖像處理算法,論述了圖像處理的理論,同時(shí)給出了VC實(shí)現(xiàn)的源代碼。 傳統(tǒng)的電腦只能處理文字、數(shù)字,最多是簡(jiǎn)單的圖形。近年來(lái),隨著電腦硬件技術(shù)的飛速發(fā)展和更新,使得計(jì)算機(jī)處理圖形圖像的能力大大增強(qiáng)。以前要用大型圖形工作站來(lái)運(yùn)行的圖形應(yīng)用軟件,或
11、是特殊文件格式的生成及對(duì)圖形所作的各種復(fù)雜的處理和轉(zhuǎn)換;如今,很普遍的家用電腦就完全可以勝任,我們可以輕易的使用PhotoShop、CorelDraw、3D MAX或是別的什么軟件做出精美的圖片或是逼真的三維物體,你甚至可以自己去做一個(gè)有趣的動(dòng)畫(huà)。 在當(dāng)今信息社會(huì),以多媒體為代表的信息技術(shù)和信息產(chǎn)業(yè)的發(fā)展和應(yīng)用對(duì)人類(lèi)社會(huì)產(chǎn)生的影響和作用愈來(lái)愈明顯,愈來(lái)愈重要。多媒體的發(fā)展和應(yīng)用,極大地推動(dòng)了諸多工業(yè)的相互滲透和飛速發(fā)展,逐步改變了整個(gè)人類(lèi)社會(huì)的工作結(jié)構(gòu)和生活方式??梢院敛豢鋸埖卣f(shuō),多媒體產(chǎn)業(yè)的形成和發(fā)展,將不僅引起計(jì)算機(jī)工業(yè)的一次革命,也將影響人類(lèi)社會(huì)發(fā)生一場(chǎng)巨大的變革。我們知道,所謂多媒
12、體,即多種信息媒介,通常包括以下幾種:文本、圖形、影像、聲音、視頻、動(dòng)畫(huà)。可以看出,多媒體的應(yīng)用在很大程度當(dāng)依賴(lài)于豐富多彩的圖形和圖像。也就是說(shuō),圖形圖像技術(shù)的飛速發(fā)展也將是必然趨勢(shì),掌握?qǐng)D形圖像處理技術(shù)對(duì)一個(gè)計(jì)算機(jī)操作人員是必要的。計(jì)算機(jī)圖形學(xué)是研究用計(jì)算機(jī)生成、處理和顯示圖形的一門(mén)科學(xué)。為了生成圖形,首先要有原始數(shù)據(jù)或數(shù)學(xué)模型(如工程人員構(gòu)思的草圖、地形航測(cè)數(shù)據(jù)、飛機(jī)的,總體方案模型等),這些數(shù)字化的輸入信息經(jīng)過(guò)計(jì)算機(jī)處理后變成圖形輸出。 圖形從原始數(shù)據(jù)生成圖象數(shù)據(jù)經(jīng)過(guò)了一系列變換過(guò)程,每個(gè)變換過(guò)程都可能產(chǎn)生不同于輸入數(shù)據(jù)的輸出數(shù)據(jù),這些數(shù)據(jù)需要按一定的結(jié)構(gòu)進(jìn)行組織,形成一系列描述圖形數(shù)
13、據(jù)的文件,我們把這類(lèi)文件稱(chēng)為圖形文件(也稱(chēng)為圖形圖象文件),而圖象文件是描述圖象數(shù)據(jù)的文件,它是圖形文件的一種特例。 在圖形生成過(guò)程中有多種類(lèi)型的數(shù)據(jù),如模型數(shù)據(jù)、場(chǎng)景數(shù)據(jù)和圖象數(shù)據(jù)等,因此,圖形文件所描述的圖形層次就不一樣,這也是產(chǎn)生多種圖形文件的一個(gè)重要原因。 另一方面,在同一個(gè)描述層上,由于每種圖形軟件包使用自己的格式保存圖形數(shù)據(jù),隨著圖形應(yīng)用軟件包的不斷增多,圖形文件的格式也會(huì)越來(lái)越多,雖然國(guó)際標(biāo)準(zhǔn)化組織(ISO)為解決圖形信息的共享問(wèn)題,建立了一系列圖形文件標(biāo)準(zhǔn)(如CGM),但是這些標(biāo)準(zhǔn)較難得到廣大用戶(hù)和廠(chǎng)商的支持,從而形成了目前這種多種圖形文件共存的局面. 圖形文件有以下特點(diǎn)
14、:(1)數(shù)據(jù)量大。由于現(xiàn)在數(shù)據(jù)獲取手段日趨先進(jìn),可以得到的數(shù)據(jù)越來(lái)越復(fù)雜,數(shù)據(jù)量也增大。(2)結(jié)構(gòu)性強(qiáng)。數(shù)據(jù)在本質(zhì)上分為數(shù)字化的和模擬的兩種。模擬信息可以轉(zhuǎn)換為數(shù)字信息。數(shù)字系統(tǒng)中的最基本單位為位(bit),其他結(jié)構(gòu)單位都以位為礎(chǔ)。在較低層次上可以是“構(gòu)造塊”(如浮點(diǎn)數(shù)、整數(shù)和字符);在較高層次上可以是記錄(如Pascal中)或結(jié)構(gòu)(如C語(yǔ)言中),而圖形文件就是由特定的結(jié)構(gòu)或記錄組成的。每種圖形文件都按自己的方式組織圖形信息,由于圖形文件包含的數(shù)據(jù)量大,所以很多圖形文件都使用一定的壓縮算法來(lái)壓縮圖形數(shù)據(jù)。 2 設(shè)備無(wú)關(guān)位圖文件的讀寫(xiě)存和縮放 2.1 BMP文件的格式 2.1.1 BMP文
15、件組成 BMP文件由文件頭、位圖信息頭、顏色信息和圖形數(shù)據(jù)四部分組成。文件頭主要包含文件的大小、文件類(lèi)型、圖像數(shù)據(jù)偏離文件頭的長(zhǎng)度等信息;位圖信息頭包含圖象的尺寸信息、圖像用幾個(gè)比特?cái)?shù)值來(lái)表示一個(gè)像素、圖像是否壓縮、圖像所用的顏色數(shù)等信息。顏色信息包含圖像所用到的顏色表,顯示圖像時(shí)需用到這個(gè)顏色表來(lái)生成調(diào)色板,但如果圖像為真彩色,既圖像的每個(gè)像素用24個(gè)比特來(lái)表示,文件中就沒(méi)有這一塊信息,也就不需要操作調(diào)色板。文件中的數(shù)據(jù)塊表示圖像的相應(yīng)的像素值,需要注意的是:圖像的像素值在文件中的存放順序?yàn)閺淖蟮接?,從下到上,也就是說(shuō),在BMP文件中首先存放的是圖像的最后一行像素,最后才存儲(chǔ)圖像的第
16、一行像素,但對(duì)與同一行的像素,則是按照先左邊后右邊的的順序存儲(chǔ)的;另外一個(gè)需要讀者朋友關(guān)注的細(xì)節(jié)是:文件存儲(chǔ)圖像的每一行像素值時(shí),如果存儲(chǔ)該行像素值所占的字節(jié)數(shù)為4的倍數(shù),則正常存儲(chǔ),否則,需要在后端補(bǔ)0,湊足4的倍數(shù)。 2.1.2 BMP文件頭 BMP文件頭數(shù)據(jù)結(jié)構(gòu)含有BMP文件的類(lèi)型、文件大小和位圖起始位置等信息。其結(jié)構(gòu)定義如下: typedef struct tagBITMAPFILEHEADER { WORD bfType; // 位圖文件的類(lèi)型,必須為"BM" DWORD bfSize; // 位圖文件的大小,以字節(jié)為單位 WORD bfReserve
17、d1; // 位圖文件保留字,必須為0 WORD bfReserved2; // 位圖文件保留字,必須為0 DWORD bfOffBits; // 位圖數(shù)據(jù)的起始位置,以相對(duì)于位圖文件頭的偏移量表示,以字節(jié)為單位 } BITMAPFILEHEADER;該結(jié)構(gòu)占據(jù)14個(gè)字節(jié)。 2.1.3 位圖信息頭 BMP位圖信息頭數(shù)據(jù)用于說(shuō)明位圖的尺寸等信息。其結(jié)構(gòu)如下: typedef struct tagBITMAPINFOHEADER{ DWORD biSize; // 本結(jié)構(gòu)所占用字節(jié)數(shù) LONG biWidth; // 位圖的寬度,以像素為單位 LONG b
18、iHeight; // 位圖的高度,以像素為單位 WORD biPlanes; // 目標(biāo)設(shè)備的平面數(shù)不清,必須為1 WORD biBitCount// 每個(gè)像素所需的位數(shù),必須是1(雙色), 4(16色),8(256色)或24(真彩色)之一 DWORD biCompression; // 位圖壓縮類(lèi)型,必須是 0(不壓縮),1(BI_RLE8壓縮類(lèi)型)或2(BI_RLE4壓縮類(lèi)型)之一 DWORD biSizeImage; // 位圖的大小,以字節(jié)為單位 LONG biXPelsPerMeter; // 位圖水平分辨率,每米像素?cái)?shù) LONG biYPelsPerMet
19、er; // 位圖垂直分辨率,每米像素?cái)?shù) DWORD biClrUsed;// 位圖實(shí)際使用的顏色表中的顏色數(shù) DWORD biClrImportant;// 位圖顯示過(guò)程中重要的顏色數(shù) } BITMAPINFOHEADER;該結(jié)構(gòu)占據(jù)40個(gè)字節(jié)。 注意:對(duì)于BMP文件格式,在處理單色圖像和真彩色圖像的時(shí)候,無(wú)論圖象數(shù)據(jù)多么龐大,都不對(duì)圖象數(shù)據(jù)進(jìn)行任何壓縮處理,一般情況下,如果位圖采用壓縮格式,那么16色圖像采用RLE4壓縮算法,256色圖像采用RLE8壓縮算法。 2.1.4 顏色表 顏色表用于說(shuō)明位圖中的顏色,它有若干個(gè)表項(xiàng),每一個(gè)表項(xiàng)是一個(gè)RGBQUAD
20、類(lèi)型的結(jié)構(gòu),定義一種顏色。RGBQUAD結(jié)構(gòu)的定義如下: typedef struct tagRGBQUAD { BYTErgbBlue;// 藍(lán)色的亮度(值范圍為0-255) BYTErgbGreen; // 綠色的亮度(值范圍為0-255) BYTErgbRed; // 紅色的亮度(值范圍為0-255) BYTErgbReserved;// 保留,必須為0 } RGBQUAD; 顏色表中RGBQUAD結(jié)構(gòu)數(shù)據(jù)的個(gè)數(shù)由BITMAPINFOHEADER 中的biBitCount項(xiàng)來(lái)確定,當(dāng)biBitCount=1,4,8時(shí),分別有2,16,256個(gè)顏色表項(xiàng),當(dāng)b
21、iBitCount=24時(shí),圖像為真彩色,圖像中每個(gè)像素的顏色用三個(gè)字節(jié)表示,分別對(duì)應(yīng)R、G、B值,圖像文件沒(méi)有顏色表項(xiàng)。位圖信息頭和顏色表組成位圖信息,BITMAPINFO結(jié)構(gòu)定義如下: typedef struct tagBITMAPINFO { BITMAPINFOHEADER bmiHeader; // 位圖信息頭 RGBQUAD bmiColors[1]; // 顏色表 } BITMAPINFO; 注意:RGBQUAD數(shù)據(jù)結(jié)構(gòu)中,增加了一個(gè)保留字段rgbReserved,它不代表任何顏色,必須取固定的值為"0",同時(shí), RGBQUAD結(jié)構(gòu)中定義的顏色值中,紅色
22、、綠色和藍(lán)色的排列順序與一般真彩色圖像文件的顏色數(shù)據(jù)排列順序恰好相反,既:若某個(gè)位圖中的一個(gè)像素點(diǎn)的顏色的描述為"00,00,ff,00",則表示該點(diǎn)為紅色,而不是藍(lán)色。 2.1.5 位圖數(shù)據(jù) 位圖數(shù)據(jù)記錄了位圖的每一個(gè)像素值或該對(duì)應(yīng)像素的顏色表的索引值,圖像記錄順序是在掃描行內(nèi)是從左到右,掃描行之間是從下到上。這種格式我們又稱(chēng)為Bottom_Up位圖,當(dāng)然與之相對(duì)的還有Up_Down形式的位圖,它的記錄順序是從上到下的,對(duì)于這種形式的位圖,也不存在壓縮形式。位圖的一個(gè)像素值所占的字節(jié)數(shù):當(dāng)biBitCount=1時(shí),8個(gè)像素占1個(gè)字節(jié);當(dāng)biBitCount=4時(shí),2個(gè)像素占
23、1個(gè)字節(jié);當(dāng) biBitCount=8時(shí),1個(gè)像素占1個(gè)字節(jié);當(dāng)biBitCount=24時(shí),1個(gè)像素占3個(gè)字節(jié),此時(shí)圖像為真彩色圖像。當(dāng)圖像不是為真彩色時(shí),圖像文件中包含顏色表,位圖的數(shù)據(jù)表示對(duì)應(yīng)像素點(diǎn)在顏色表中相應(yīng)的索引值,當(dāng)為真彩色時(shí),每一個(gè)像素用三個(gè)字節(jié)表示圖像相應(yīng)像素點(diǎn)彩色值,每個(gè)字節(jié)分別對(duì)應(yīng)R、G、B分量的值,這時(shí)候圖像文件中沒(méi)有顏色表。上面我已經(jīng)講過(guò)了,Windows規(guī)定圖像文件中一個(gè)掃描行所占的字節(jié)數(shù)必須是4的倍數(shù)(即以字為單位),不足的以0填充,圖像文件中一個(gè)掃描行所占的字節(jié)數(shù)計(jì)算方法: DataSizePerLine= (biWidth* biBitCount+31)/
24、8;// 一個(gè)掃描行所占的字節(jié) 位圖數(shù)據(jù)的大小按下式計(jì)算(不壓縮情況下): DataSize= DataSizePerLine* biHeight。 2.2 BMP文件的讀寫(xiě) 如今Windows(3.x以及95,98,NT)系列已經(jīng)成為絕大多數(shù)用戶(hù)使用的操作系統(tǒng),它比DOS成功的一個(gè)重要因素是它可視化的漂亮界面。那么Windows是如何顯示圖象的呢?這就要談到位圖(bitmap)。 我們知道,普通的顯示器屏幕是由許許多多點(diǎn)構(gòu)成的,我們稱(chēng)之為象素。顯示時(shí)采用掃描的方法:電子槍每次從左到右掃描一行,為每個(gè)象素著色,然后從上到下這樣掃描若干行,就掃過(guò)了一屏。為了防止閃爍,每秒要重復(fù)上述過(guò)
25、程幾十次。例如我們常說(shuō)的屏幕分辨率為640480,刷新頻率為70Hz,意思是說(shuō)每行要掃描640個(gè)象素,一共有480行,每秒重復(fù)掃描屏幕70次。我們稱(chēng)這種顯示器為位映象設(shè)備。所謂位映象,就是指一個(gè)二維的象素矩陣,而位圖就是采用位映象方法顯示和存儲(chǔ)的圖象。舉個(gè)例子,圖1.1是一幅普通的黑白位圖,圖1.2是被放大后的圖,圖中每個(gè)方格代表了一個(gè)象素。我們可以看到:整個(gè)骷髏就是由這樣一些黑點(diǎn)和白點(diǎn)組成的。 先來(lái)說(shuō)說(shuō)三元色RGB概念。我們知道,自然界中的所有顏色都可以由紅、綠、藍(lán)(R,G,B)組合而成。有的顏色含有紅色成分多一些,如深紅;有的含有紅色成分少一些,如淺紅。針對(duì)含有紅色成分的多少,可以分成0
26、到255共256個(gè)等級(jí),0級(jí)表示不含紅色成分;255級(jí)表示含有100%的紅色成分。同樣,綠色和藍(lán)色也被分成256級(jí)。這種分級(jí)概念稱(chēng)為量化。 這樣,根據(jù)紅、綠、藍(lán)各種不同的組合我們就能表示出256256256,約1600萬(wàn)種顏色。這么多顏色對(duì)于我們?nèi)搜蹃?lái)說(shuō)已經(jīng)足夠豐富了。 表1.1 常見(jiàn)顏色的RGB組合值 顏色 R G B 紅 255 0 0 藍(lán) 0 255 0 綠 0 0 255 黃 255 255 0 紫 255 0 255 青 0 255 255 白 255 255 255 黑 0 0 0 灰 128
27、 128 128 在實(shí)現(xiàn)數(shù)字圖象處理的過(guò)程中,主要是通過(guò)對(duì)圖像中的每一個(gè)像素點(diǎn)運(yùn)用各種圖像處理算法來(lái)達(dá)到預(yù)期的效果,所以進(jìn)行圖像處理的第一步,也是我們最關(guān)心的問(wèn)題,是如何得到圖像中每一個(gè)像素點(diǎn)的亮度值;為了觀(guān)察和驗(yàn)證處理的圖像效果,另一個(gè)需要解決的問(wèn)題是如何將處理前后的圖像正確的顯示出來(lái)。我們這章內(nèi)容就是解決這些問(wèn)題。 隨著科技的發(fā)展,圖像處理技術(shù)已經(jīng)滲透到人類(lèi)生活的各個(gè)領(lǐng)域并得到越來(lái)越多的應(yīng)用,但是突出的一個(gè)矛盾是圖像的格式也是越來(lái)越多,目前圖像處理所涉及的主要的圖像格式就有很多種,如TIF、JEMP、BMP等等,一般情況下,為了處理簡(jiǎn)單方便,進(jìn)行數(shù)字圖像處理所采用的都
28、是BMP格式的圖像文件(有時(shí)也稱(chēng)為DIB格式的圖像文件),并且這種格式的文件是沒(méi)有壓縮的。我們通過(guò)操作這種格式的文件,可以獲取正確顯示圖像所需的調(diào)色板信息,圖像的尺寸信息,圖像中各個(gè)像素點(diǎn)的亮度信息等等,有了這些數(shù)據(jù),開(kāi)發(fā)人員就可以對(duì)圖像施加各種處理算法,進(jìn)行相應(yīng)的處理。如果特殊情況下需要處理其它某種格式的圖像,如GIF、JEMP等格式的圖象文件,可以首先將該格式轉(zhuǎn)換為BMP格式,然后再進(jìn)行相應(yīng)的處理。這一點(diǎn)需要讀者清楚。 BMP格式的圖像文件又可以分為許多種類(lèi),如真彩色位圖、256色位圖,采用RLE(游程編碼)壓縮格式的BMP位圖等等。由于在實(shí)際的工程應(yīng)用和圖像算法效果驗(yàn)證中經(jīng)常要處
29、理的是256級(jí)并且是沒(méi)有壓縮的BMP灰度圖像,例如通過(guò)黑白采集卡采集得到的圖像就是這種格式,所以我們?cè)谡麄€(gè)講座中范例所處理的文件格式都是BMP灰度圖像。如果讀者對(duì)這種格式的位圖能夠作到熟練的操作,那么對(duì)于其余形式的BMP位圖的操作也不會(huì)很困難。 BMP灰度圖像作為Windows環(huán)境下主要的圖像格式之一,以其格式簡(jiǎn)單,適應(yīng)性強(qiáng)而倍受歡迎。正如我們?cè)谏弦恢v中介紹過(guò)的那樣,這種文件格式就是每一個(gè)像素用8bit表示,顯示出來(lái)的圖像是黑白效果,最黑的像素的灰度(也叫作亮度)值為"0",最白的像素的灰度值為"255",整個(gè)圖像各個(gè)像素的灰度值隨機(jī)的分布在"0"到"255"的區(qū)間中,越黑的像素,其灰
30、度值越接近于"0",越白(既越亮)的像素,其灰度值越接近于"255";與此對(duì)應(yīng)的是在該文件類(lèi)型中的顏色表項(xiàng)的各個(gè)RGB分量值是相等的,并且顏色表項(xiàng)的數(shù)目是256個(gè)。 在進(jìn)行圖像處理時(shí),操作圖像中的像素值就要得到圖像陣列;經(jīng)過(guò)處理后的圖像的像素值需要存儲(chǔ)起來(lái);顯示圖像時(shí)要正確實(shí)現(xiàn)調(diào)色板、得到位圖的尺寸信息等。 可以根據(jù)BMP位圖文件的結(jié)構(gòu),操作BMP位圖文件并讀入圖像數(shù)據(jù),為此我們充分利用了VC的對(duì)話(huà)框結(jié)構(gòu),自己新建ReadDIBFile()函數(shù),這樣用戶(hù)就可以在自動(dòng)生成程序的打開(kāi)文件對(duì)話(huà)框中選擇所要打開(kāi)的位圖文件,然后程序?qū)⒆詣?dòng)調(diào)用該函數(shù)執(zhí)行讀取數(shù)據(jù)的操作。該函數(shù)的實(shí)現(xiàn)代碼如下所示
31、 HDIB WINAPI ReadDIBFile(CFile& file) { BITMAPFILEHEADER bmfHeader; DWORD dwBitsSize; HDIB hDIB; LPSTR pDIB; // 獲取DIB(文件)長(zhǎng)度(字節(jié)) dwBitsSize = file.GetLength(); // 嘗試讀取DIB文件頭 if (file.Read((LPSTR)&bmfHeader, sizeof(bmfHeader)) != sizeof(bmfHeader)) { // 大小不對(duì),返回NULL。 return NUL
32、L; } // 判斷是否是DIB對(duì)象,檢查頭兩個(gè)字節(jié)是否是"BM" if (bmfHeader.bfType != DIB_HEADER_MARKER) { // 非DIB對(duì)象,返回NULL。 return NULL; } // 為DIB分配內(nèi)存 hDIB = (HDIB) ::GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, dwBitsSize); if (hDIB == 0) { // 內(nèi)存分配失敗,返回NULL。 return NULL; } // 鎖定 pDIB = (L
33、PSTR) ::GlobalLock((HGLOBAL) hDIB); // 讀象素 if (file.ReadHuge(pDIB, dwBitsSize - sizeof(BITMAPFILEHEADER)) != dwBitsSize - sizeof(BITMAPFILEHEADER) ) { // 大小不對(duì)。 // 解除鎖定 ::GlobalUnlock((HGLOBAL) hDIB); // 釋放內(nèi)存 ::GlobalFree((HGLOBAL) hDIB); // 返回NULL。 return
34、NULL; } // 解除鎖定 ::GlobalUnlock((HGLOBAL) hDIB); // 返回DIB句柄 return hDIB; } 呼叫兩個(gè)函數(shù)之一來(lái)顯示DIB時(shí),您需要幾個(gè)關(guān)于圖像的信息。如果除了文件表頭外,整個(gè)文件被儲(chǔ)存在內(nèi)存的連續(xù)區(qū)塊中,指向該內(nèi)存塊開(kāi)始處(也就是信息表頭的開(kāi)頭)的指標(biāo)被稱(chēng)為指向packed DIB的指標(biāo)。因?yàn)檎麄€(gè)DIB由單個(gè)指標(biāo)(如pPackedDib)引用,所以packed DIB是在內(nèi)存中儲(chǔ)存DIB的方便方法,您可以把指標(biāo)定義為指向BYTE的指標(biāo)。使用本章前面所示的結(jié)構(gòu)定義,能得到所有儲(chǔ)存在DIB內(nèi)的信息,包括色彩對(duì)照表
35、和個(gè)別圖素位。然而,要想得到這么多信息,還需要一些程序代碼。例如,您不能通過(guò)以下敘述簡(jiǎn)單地取得DIB的圖素寬度:iWidth = ((PBITMAPINFOHEADER) pPackedDib)->biWidth ; DIB有可能是OS/2兼容格式的。在那種格式中,packed DIB以BITMAPCOREHEADER結(jié)構(gòu)開(kāi)始,并且DIB的圖素寬度和高度以16位WORD,而不是32位LONG儲(chǔ)存。因此,首先必須檢查DIB是否為舊的格式,然后進(jìn)行相對(duì)應(yīng)的操作: if(((PBITMAPCOREHEADER) pPackedDib)->bcSize == sizeof (BITMAPCOREHE
36、ADER)) iWidth = ((PBITMAPCOREHEADER) pPackedDib)->bcWidth ; else iWidth = ((PBITMAPINFOHEADER) pPackedDib)->biWidth ; SetDIBitsToDevice和StretchDIBits函數(shù)需要兩個(gè)指向DIB的指標(biāo),因?yàn)檫@兩個(gè)部分不在連續(xù)的內(nèi)存塊內(nèi)。確實(shí),把DIB分成兩個(gè)內(nèi)存塊是很有用的,只是我們更喜歡與整個(gè)DIB儲(chǔ)存在單個(gè)內(nèi)存塊的packed DIB打交道。除了這兩個(gè)指標(biāo),SetDIBitsToDevice和StretchDIBit
37、s函數(shù)通常也需要DIB的圖素寬度和高度。如只想顯示DIB的一部分,就不必明確地知道這些值,但它們會(huì)定義您在DIB圖素位數(shù)組內(nèi)定義的矩形的上限。點(diǎn)對(duì)點(diǎn)圖素顯示 SetDIBitsToDevice函數(shù)顯示沒(méi)有延伸和縮小的DIB。DIB的每個(gè)圖素對(duì)應(yīng)到輸出設(shè)備的一個(gè)圖素上,而且DIB中的圖像一定會(huì)被正確顯示出來(lái)-也就是說(shuō),圖像的頂列在上方。任何會(huì)影響設(shè)備內(nèi)容的坐標(biāo)轉(zhuǎn)換都影響了顯示DIB的開(kāi)始位置,但不影響顯示出來(lái)的圖片大小和方向。 不要對(duì)參數(shù)的數(shù)量感到厭煩,在多數(shù)情況下,函數(shù)用起來(lái)比看起來(lái)要簡(jiǎn)單。不過(guò)在其它用途上來(lái)說(shuō),它的用法真的是亂七八糟,不過(guò)我們將學(xué)會(huì)怎么用它。 和GDI顯示函數(shù)一樣,Set
38、DIBitsToDevice的第一個(gè)參數(shù)是設(shè)備內(nèi)容句柄,它指出顯示DIB的設(shè)備。下面兩個(gè)參數(shù)xDst和yDst,是輸出設(shè)備的邏輯坐標(biāo),并指出了顯示DIB圖像左上角的坐標(biāo)(「上端」指的是視覺(jué)上的上方,并不是DIB圖素的第一行)。注意,這些都是邏輯坐標(biāo),因此它們附屬于實(shí)際上起作用的任何坐標(biāo)轉(zhuǎn)換方式或-在Windows NT的情況下-設(shè)定的任何空間轉(zhuǎn)換。在內(nèi)定的MM_TEXT映像方式下,可以把這些參數(shù)設(shè)為0,從顯示平面上向左向上顯示DIB圖像。 可以顯示整個(gè)DIB圖像或僅顯示其中的一部分,這就是后四個(gè)參數(shù)的作用。但是DIB圖素?cái)?shù)據(jù)的由上而下的方向產(chǎn)生了許多誤解,待會(huì)兒會(huì)談到這些?,F(xiàn)在應(yīng)該清楚當(dāng)顯
39、示整個(gè)DIB時(shí),應(yīng)把xSrc和ySrc設(shè)定為0,并且cxSrc和cySrc應(yīng)分別等于DIB的圖素寬度和高度。注意,因?yàn)锽ITMAPINFOHEADER結(jié)構(gòu)的biHeight字段對(duì)于由上而下的DIB來(lái)說(shuō)是負(fù)的,cySrc應(yīng)設(shè)定為biHeight字段的絕對(duì)值。 pBits參數(shù)是指向DIB圖素位的指針。pInfo參數(shù)是指向DIB的BITMAPINFO結(jié)構(gòu)的指針。雖然BITMAPINFO結(jié)構(gòu)的地址與BITMAPINFOHEADER結(jié)構(gòu)的地址相同,但是SetDIBitsToDevice結(jié)構(gòu)被定義為使用BITMAPINFO結(jié)構(gòu),暗示著:對(duì)于1位、4位和8位DIB,位圖信息表頭后必須跟著色彩對(duì)照表。盡管p
40、Info參數(shù)被定義為指向BITMAPINFO結(jié)構(gòu)的指針,它也是指向BITMAPCOREINFO、BITMAPV4HEADER或BITMAPV5HEADER結(jié)構(gòu)的指針。 2.3 BMP文件的保存 /************************************************************************* * * 函數(shù)名稱(chēng): * SaveDIB() * * 參數(shù): * HDIB hDib - 要保存的DIB * CFile& file - 保存文件CFile * * 返回值
41、: * BOOL - 成功返回TRUE,否則返回FALSE或者CFileException * * 說(shuō)明: * 該函數(shù)將指定的DIB對(duì)象保存到指定的CFile中。該CFile由調(diào)用程序打開(kāi)和關(guān)閉。 * *************************************************************************/ BOOL WINAPI SaveDIB(HDIB hDib, CFile& file) { // Bitmap文件頭 BITMAPFILEHEADER bmfHdr;
42、 // 指向BITMAPINFOHEADER的指針 LPBITMAPINFOHEADER lpBI; // DIB大小 DWORD dwDIBSize; if (hDib == NULL) { // 如果DIB為空,返回FALSE return FALSE; } // 讀取BITMAPINFO結(jié)構(gòu),并鎖定 lpBI = (LPBITMAPINFOHEADER) ::GlobalLock((HGLOBAL) hDib); if (lpBI == NULL) { // 為空,返回FALSE return F
43、ALSE; } // 判斷是否是WIN3.0 DIB if (!IS_WIN30_DIB(lpBI)) { // 不支持其它類(lèi)型的DIB保存 // 解除鎖定 ::GlobalUnlock((HGLOBAL) hDib); // 返回FALSE return FALSE; } // 填充文件頭 // 文件類(lèi)型"BM" bmfHdr.bfType = DIB_HEADER_MARKER; // 計(jì)算DIB大小時(shí),最簡(jiǎn)單的方法是調(diào)用GlobalSize()函數(shù)。但是全局內(nèi)存大小并 // 不是DIB
44、真正的大小,它總是多幾個(gè)字節(jié)。這樣就需要計(jì)算一下DIB的真實(shí)大小。 // 文件頭大?。伾泶笮? // (BITMAPINFOHEADER和BITMAPCOREHEADER結(jié)構(gòu)的第一個(gè)DWORD都是該結(jié)構(gòu)的大小) dwDIBSize = *(LPDWORD)lpBI + ::PaletteSize((LPSTR)lpBI); // 計(jì)算圖像大小 if ((lpBI->biCompression == BI_RLE8) || (lpBI->biCompression == BI_RLE4)) { // 對(duì)于RLE位圖,沒(méi)法計(jì)算大小,只能信任biSizeI
45、mage內(nèi)的值 dwDIBSize += lpBI->biSizeImage; } else { // 象素的大小 DWORD dwBmBitsSize; // 大小為Width * Height dwBmBitsSize = WIDTHBYTES((lpBI->biWidth)*((DWORD)lpBI->biBitCount)) * lpBI->biHeight; // 計(jì)算出DIB真正的大小 dwDIBSize += dwBmBitsSize; // 更新biSizeImage(很多BMP文件頭中biSizeIm
46、age的值是錯(cuò)誤的) lpBI->biSizeImage = dwBmBitsSize; } // 計(jì)算文件大?。篋IB大小+BITMAPFILEHEADER結(jié)構(gòu)大小 bmfHdr.bfSize = dwDIBSize + sizeof(BITMAPFILEHEADER); // 兩個(gè)保留字 bmfHdr.bfReserved1 = 0; bmfHdr.bfReserved2 = 0; // 計(jì)算偏移量bfOffBits,它的大小為Bitmap文件頭大小+DIB頭大?。伾泶笮? bmfHdr.bfOffBits = (DWORD)sizeof(
47、BITMAPFILEHEADER) + lpBI->biSize + PaletteSize((LPSTR)lpBI); // 嘗試寫(xiě)文件 TRY { // 寫(xiě)文件頭 file.Write((LPSTR)&bmfHdr, sizeof(BITMAPFILEHEADER)); // 寫(xiě)DIB頭和象素 file.WriteHuge(lpBI, dwDIBSize); } CATCH (CFileException, e) { // 解除鎖定 ::GlobalUnlock((HGLOBAL) hDib);
48、 // 拋出異常 THROW_LAST(); } END_CATCH // 解除鎖定 ::GlobalUnlock((HGLOBAL) hDib); // 返回TRUE return TRUE; } 2.4 BMP文件的縮放 由于放大圖象時(shí)產(chǎn)生了新的象素,以及浮點(diǎn)數(shù)的操作,得到的坐標(biāo)可能并不是整數(shù),這一點(diǎn)我們?cè)诮榻B旋轉(zhuǎn)時(shí)就提到了。我們采用的做法是找與之最臨近的點(diǎn)。實(shí)際上,更精確的做法是采用插值(interpolation),即利用鄰域的象素來(lái)估計(jì)新的象素值。其實(shí)我們前面的做法也是一種插值,稱(chēng)為最鄰近插值(Nearest Nei
49、ghbour Interpolation)。下面先介紹線(xiàn)形插值(Linear Interpolation)。 線(xiàn)形插值使用原圖中兩個(gè)值來(lái)構(gòu)造所求坐標(biāo)處的值。舉一個(gè)一維的例子。如圖2.16所示,如果已經(jīng)知道了兩點(diǎn)x0,x2處的函數(shù)值f(x0),f(x2),現(xiàn)在要求x1處的函數(shù)值f(x1)。我們假設(shè)函數(shù)是線(xiàn)形的,利用幾何知識(shí)可以知道 f(x1)=(f(x2)-f(x0))(x1-x0)/(x2-x0)+f(x0) 在圖象處理中需要將線(xiàn)形插值擴(kuò)展到二維的情況,即采用雙線(xiàn)形插值(Bilinear Intrepolation). 圖2.17為雙線(xiàn)形插值的示意圖。 圖2.16 線(xiàn)形插值的示意圖
50、 圖.217 雙線(xiàn)形插值的示意圖 已知a、b、c、d四點(diǎn)的灰度,要求e點(diǎn)的灰度,可以先在水平方向上由a,b線(xiàn)形插值求出g、c、d線(xiàn)形插值求出f,然后在垂直方向上由g,f線(xiàn)形插值求出e。 線(xiàn)形插值基于這樣的假設(shè):原圖的灰度在兩個(gè)象素之間是線(xiàn)形變化的。一般情況下,這種插值的效果還不錯(cuò)。更精確的方法是采用曲線(xiàn)插值(Curvilinear Interpolation),即認(rèn)為象素之間的灰度變化規(guī)律符合某種曲線(xiàn),但這種處理的計(jì)算量是很大的。 /*************************************************************************
51、 * * 函數(shù)名稱(chēng): * ZoomDIB() * * 參數(shù): * LPSTR lpDIB - 指向源DIB的指針 * float fXZoomRatio - X軸方向縮放比率 * float fYZoomRatio - Y軸方向縮放比率 * * 返回值: * HGLOBAL - 縮放成功返回新DIB句柄,否則返回NULL。 * * 說(shuō)明: * 該函數(shù)用來(lái)縮放DIB圖像,返回新生成DIB的句柄。 * *********************************************
52、***************************/ HGLOBAL WINAPI ZoomDIB(LPSTR lpDIB, float fXZoomRatio, float fYZoomRatio) { // 源圖像的寬度和高度 LONG lWidth; LONG lHeight; // 縮放后圖像的寬度和高度 LONG lNewWidth; LONG lNewHeight; // 縮放后圖像的寬度(lNewWidth,必須是4的倍數(shù)) LONG lNewLineBytes; // 指向源圖像的指針 LPSTR lp
53、DIBBits; // 指向源象素的指針 LPSTR lpSrc; // 縮放后新DIB句柄 HDIB hDIB; // 指向縮放圖像對(duì)應(yīng)象素的指針 LPSTR lpDst; // 指向縮放圖像的指針 LPSTR lpNewDIB; LPSTR lpNewDIBBits; // 指向BITMAPINFO結(jié)構(gòu)的指針(Win3.0) LPBITMAPINFOHEADER lpbmi; // 指向BITMAPCOREINFO結(jié)構(gòu)的指針 LPBITMAPCOREHEADER lpbmc; // 循環(huán)變量(
54、象素在新DIB中的坐標(biāo)) LONG i; LONG j; // 象素在源DIB中的坐標(biāo) LONG i0; LONG j0; // 圖像每行的字節(jié)數(shù) LONG lLineBytes; // 找到源DIB圖像象素起始位置 lpDIBBits = ::FindDIBBits(lpDIB); // 獲取圖像的寬度 lWidth = ::DIBWidth(lpDIB); // 計(jì)算圖像每行的字節(jié)數(shù) lLineBytes = WIDTHBYTES(lWidth * 8); // 獲取圖像的高度 lHeight
55、= ::DIBHeight(lpDIB); // 計(jì)算縮放后的圖像實(shí)際寬度 // 此處直接加0.5是由于強(qiáng)制類(lèi)型轉(zhuǎn)換時(shí)不四舍五入,而是直接截去小數(shù)部分 lNewWidth = (LONG) (::DIBWidth(lpDIB) * fXZoomRatio + 0.5); // 計(jì)算新圖像每行的字節(jié)數(shù) lNewLineBytes = WIDTHBYTES(lNewWidth * 8); // 計(jì)算縮放后的圖像高度 lNewHeight = (LONG) (lHeight * fYZoomRatio + 0.5); // 分配內(nèi)存,以保存新D
56、IB hDIB = (HDIB) ::GlobalAlloc(GHND, lNewLineBytes * lNewHeight + *(LPDWORD)lpDIB + ::PaletteSize(lpDIB)); // 判斷是否內(nèi)存分配失敗 if (hDIB == NULL) { // 分配內(nèi)存失敗 return NULL; } // 鎖定內(nèi)存 lpNewDIB = (char * )::GlobalLock((HGLOBAL) hDIB); // 復(fù)制DIB信息頭和調(diào)色板 memcpy(lpNewDIB, lpDIB, *(
57、LPDWORD)lpDIB + ::PaletteSize(lpDIB)); // 找到新DIB象素起始位置 lpNewDIBBits = ::FindDIBBits(lpNewDIB); // 獲取指針 lpbmi = (LPBITMAPINFOHEADER)lpNewDIB; lpbmc = (LPBITMAPCOREHEADER)lpNewDIB; // 更新DIB中圖像的高度和寬度 if (IS_WIN30_DIB(lpNewDIB)) { // 對(duì)于Windows 3.0 DIB lpbmi->biWidth = lNew
58、Width; lpbmi->biHeight = lNewHeight; } else { // 對(duì)于其它格式的DIB lpbmc->bcWidth = (unsigned short) lNewWidth; lpbmc->bcHeight = (unsigned short) lNewHeight; } // 針對(duì)圖像每行進(jìn)行操作 for(i = 0; i < lNewHeight; i++) { // 針對(duì)圖像每列進(jìn)行操作 for(j = 0; j < lNewWidth; j++) { // 指
59、向新DIB第i行,第j個(gè)象素的指針 // 注意此處寬度和高度是新DIB的寬度和高度 lpDst = (char *)lpNewDIBBits + lNewLineBytes * (lNewHeight - 1 - i) + j; // 計(jì)算該象素在源DIB中的坐標(biāo) i0 = (LONG) (i / fYZoomRatio + 0.5); j0 = (LONG) (j / fXZoomRatio + 0.5); // 判斷是否在源圖范圍內(nèi) if( (j0 >= 0) && (j0 < lWidth) && (i0 >=
60、0) && (i0 < lHeight)) { // 指向源DIB第i0行,第j0個(gè)象素的指針 lpSrc = (char *)lpDIBBits + lLineBytes * (lHeight - 1 - i0) + j0; // 復(fù)制象素 *lpDst = *lpSrc; } else { // 對(duì)于源圖中沒(méi)有的象素,直接賦值為255 * ((unsigned char*)lpDst) = 255; } } } // 返回 r
61、eturn hDIB; } 3 圖像合成的具體方法 3.1 圖片合成算法詳解 首先,要能取得前景圖與背景圖顏色的 RGB三基色,然后用r,g,b 為最后取得的顏色值;r1,g1,b1是上層的顏色值;r2,g2,b2是下層顏色值 r = r1/2 + r2/2; g = g1/2 + g2/2; b = b1/2 + b2/2; 以上為50%透明。若要使用不同的透明度用以下算法(ALPHA=透明度): (50%以下) r = r1 - r1/ALPHA + r2/ALPHA; g = g1 - g1/ALPHA + g2/ALPHA; b = b1 - b1/ALPHA
62、+ b2/ALPHA; (50%以上) r = r1/ALPHA + r2 - r2/ALPHA; g = g1/ALPHA + g2 - g2/ALPHA; b = b1/ALPHA + b2 - b2/ALPHA; 在32/64K色模式下,由于每個(gè)點(diǎn)的RGB值是放在一個(gè)字里,以16位色為例,一般是按RGB或BGR 565存放。傳統(tǒng)的軟件Alpha混合算法是先將RGB分離出來(lái),分開(kāi)運(yùn)算,然后再合成。這造成了16位模式下的alpha混合比24位模式下慢 的現(xiàn)象,但使用16位色真的那么慢嗎?我認(rèn)為如果不使用MMX指令,15/16的比24位的快。因?yàn)槲覀兛梢允褂靡粋€(gè)小的技巧來(lái)同時(shí)計(jì)算RG
63、B。而24位顏色,除非使用MMX指令,否則必須分開(kāi)計(jì)算R、G、B。 先設(shè)顏色(color)是RGB 565的,那么按二進(jìn)制看,這個(gè)顏色字是這樣分布的: RRRRR GGGGGG BBBBB 5位 6位 5位 RGB成分 而386以上CPU都有32位的寄存器,我們只需要將16位RGB變形為: 00000 GGGGGG 00000 RRRRR 000000 BBBBB 5位 6位 5位 5位 6位 5位 變形后的RGB成分 儲(chǔ)存在32位寄存器中,(就是把綠色提到前16位里)由于64K色下顏色深度是32級(jí)的,所以alpha也只用分32級(jí)就能滿(mǎn)足
64、需要。那么對(duì)上面變形過(guò)的雙字處理,可以同時(shí)算RGB了。(Color1*Alpha+Color2*(32-Alpha))/32能不能簡(jiǎn)化為(Color1-Color2)*Alpha/32+Color2. 以為減法將產(chǎn)生負(fù)數(shù),這樣再算乘法時(shí)有可能出問(wèn)題,但是經(jīng)過(guò)測(cè)試,這樣簡(jiǎn)化似乎又沒(méi)有問(wèn)題。畢竟極小的誤差是可以忽略的。 3.2 圖片合成算法集的實(shí)現(xiàn) m_dibMake=m_dibBack; CPalette m_palette; ::CreateDIBPalette(m_dibMake , &m_palette); LPSTR lpDIB = (LPSTR) ::Glob
65、alLock((HGLOBAL) m_dibMake ); // 獲取DIB寬度 int cxDIB = (int) ::DIBWidth(lpDIB); // 獲取DIB高度 int cyDIB = (int) ::DIBHeight(lpDIB); ::GlobalUnlock((HGLOBAL) m_dibMake); CDC *pDC; CWnd *pWnd0= GetDlgItem(IDC_MAKE); pDC = pWnd0->GetDC(); CRect rc; pDC->GetWindow()->GetCl
66、ientRect(&rc); CRect rcDIB; rcDIB.top = rcDIB.left=0; rcDIB.right = cxDIB; rcDIB.bottom = cyDIB; HBITMAP hBitmap_front=DIBToBitmap(m_dibFront, m_palette); HBITMAP hBitmap_back=DIBToBitmap(m_dibBack, m_palette); CBitmap bmp1,bmp2; BITMAP bmpX,bmpY; bmp1.Attach(hBitmap_front); bmp2.Attach(hBitmap_back); bmp1.GetBitmap(&bmpX); UINT* bmpBuffer=(UINT*)GlobalAlloc(GPTR,bmpX.bmWidthBytes*bmpX.bmHeight); bmp1.GetBitmapB
- 溫馨提示:
1: 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
2: 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
3.本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
5. 裝配圖網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 造紙納米碳酸鈣
- 2019中考物理第1章機(jī)械運(yùn)動(dòng)復(fù)習(xí)課件新人教版1
- LRBG的技能模型與角色模型
- 轉(zhuǎn)子間骨折的個(gè)手術(shù)技巧
- 生命之源血液
- 表情符號(hào)與藝術(shù)-美術(shù)ppt課件
- 壓力管理和積極心態(tài)
- 部編版初中語(yǔ)文春優(yōu)質(zhì)課課件
- 教育行業(yè)聯(lián)盟解決方案培訓(xùn)-new
- 控制與接口技術(shù)-基于模糊推理的智能控制 1226
- 八年級(jí)物理-聲音的特征-課件
- 藤野先生余映潮教案課件
- 興趣及其培養(yǎng)(發(fā)展職業(yè)生涯要立足本人實(shí)際)詳解課件
- 學(xué)會(huì)調(diào)控情緒_課件(教育精品)
- (廣州版)五年級(jí)英語(yǔ)下冊(cè)課件-Module-4-Unit-112