bmp的特效處理_第1頁
bmp的特效處理_第2頁
bmp的特效處理_第3頁
bmp的特效處理_第4頁
bmp的特效處理_第5頁
已閱讀5頁,還剩12頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

1、隨著科技的發(fā)展,圖像處理技術(shù)已經(jīng)滲透到人類生活的各個領(lǐng)域并得到越來越多的應(yīng)用,但是突出的一個矛盾是圖像的格式也是越來越多,目前圖像處理所涉 及的主要的圖像格式就有很多種,如TIF、JEMP、BMP等等,一般情況下,為了處理簡單方便,進(jìn)行數(shù)字圖像處理所采用的都是BMP格式的圖像文件(有 時也稱為DIB格式的圖像文件),并且這種格式的文件是沒有壓縮的。我們通過操作這種格式的文件,可以獲取正確顯示圖像所需的調(diào)色板信息,圖像的尺寸信 息,圖像中各個像素點(diǎn)的亮度信息等等,有了這些數(shù)據(jù),開發(fā)人員就可以對圖像施加各種處理算法,進(jìn)行相應(yīng)的處理。這一點(diǎn)需要讀者清楚。BMP格式的圖像 文件又可以分為許多種類,如真

2、彩色位圖、256色位圖,采用RLE(游程編碼)壓縮格式的BMP位圖等等。由于在實(shí)際的工程應(yīng)用和圖像算法效果驗(yàn)證中經(jīng)常 要處理的是256級并且是沒有壓縮的BMP灰度圖像,例如通過黑白采集卡采集得到的圖像就是這種格式,所以我們在整個講座中范例所處理的文件格式都是 BMP灰度圖像。如果讀者對這種格式的位圖能夠作到熟練的操作,那么對于其余形式的BMP位圖的操作也不會很困難。 BMP灰度圖像作為Windows環(huán)境下主要的圖像格式之一,以其格式簡單,適應(yīng)性強(qiáng)而倍受歡迎。正如我們在上一講中介紹過的那樣,這種文件格式就是每一 個像素用8bit表示,顯示出來的圖像是黑白效果,最黑的像素的灰度(也叫作亮度)值為0

3、,最白的像素的灰度值為 255,整個圖像各個像素的灰度值隨機(jī)的分布在0到255的區(qū)間中,越黑的像素,其灰度值越接近于0,越白(既越亮)的像素,其灰度值越接近于255;與 此對應(yīng)的是在該文件類型中的顏色表項(xiàng)的各個RGB分量值是相等的,并且顏色表項(xiàng)的數(shù)目是256個。結(jié)合這些問題,下面我們針對性的給出了操作灰度 BMP圖像時的部分函數(shù)實(shí)現(xiàn)代碼及注釋。 一、 BMP位圖操作首先我們回顧一下上講中的重要信息:BMP位圖包括位圖文件頭結(jié)構(gòu)BITMAPFILEHEADER、位圖信息頭結(jié)構(gòu) BITMAPINFOHEADER、位圖顏色表RGBQUAD和位圖像素?cái)?shù)據(jù)四部分。處理位圖時要根據(jù)文件的這些結(jié)構(gòu)得到位圖文

4、件大小、位圖的寬、高、實(shí) 現(xiàn)調(diào)色板、得到位圖像素值等等。這里要注意的一點(diǎn)是在BMP位圖中,位圖的每行像素值要填充到一個四字節(jié)邊界,即位圖每行所占的存儲長度為四字節(jié)的倍數(shù), 不足時將多余位用0填充。 有了上述知識,可以開始編寫圖像處理的程序了,關(guān)于在VC的開發(fā)平臺上如何開發(fā)程序的問題這里不再贅述。在開發(fā)該圖像處理程序的過程中,筆者沒有采用面向 對象的方法,雖然面向?qū)ο蟮姆椒梢詫?shù)據(jù)封裝起來,保護(hù)類中的數(shù)據(jù)不受外界的干擾,提高數(shù)據(jù)的安全性,但是這種安全性是以降低程序的執(zhí)行效率為代價的, 為此,我們充分利用了程序的文檔視圖結(jié)構(gòu),在程序中直接使用了一些API函數(shù)來操作圖像。在微軟的MSDN中有一個名

5、為Diblook的例子,該例子演示 了如何操作Dib位圖,有興趣的讀者可以參考一下,相信一定會有所收獲。 啟動Visual C+,生成一個名為Dib的多文檔程序,將CDibView類的基類設(shè)為CscrollView類,這樣作的目的是為了在顯示位圖時支持滾動條,另外在 處理圖像應(yīng)用程序的文檔類(CDibDoc.h)中聲明如下宏及公有變量:最后將程序的字符串表中的字符串資源IDR_DibTYPE修改為:nDibnDibnDib Files(*.bmp;*.dib)n.bmpnDib.DocumentnDib Document。這樣作的目的是為了在程序文件對話框中可以選擇BMP或DIB格式的位圖文件

6、。 1、 讀取灰度BMP位圖可以根據(jù)BMP位圖文件的結(jié)構(gòu),操作BMP位圖文件并讀入圖像數(shù)據(jù),為此我們充分利用了VC的文檔視圖結(jié)構(gòu),重載了文擋類的 OnOpenDocument()函數(shù),這樣用戶就可以在自動生成程序的打開文件對話框中選擇所要打開的位圖文件,然后程序?qū)⒆詣诱{(diào)用該函數(shù)執(zhí)行讀取數(shù)據(jù) 的操作。該函數(shù)的實(shí)現(xiàn)代碼如下所示:上面的方法是通過CFile類對象的操作來讀取位圖文件的,它需要分析位圖中的文件頭信息,從而確定需要讀取的圖 像長度。這種方法相對來說有些繁瑣,其實(shí)還可以以一種相對簡單的方法讀取位圖數(shù)據(jù),首先在程序的資源中定義DIB類型資源,然后添加位圖到該類型中,將圖 像數(shù)據(jù)以資源的形式讀

7、取出來,這時候就可以根據(jù)所獲取的數(shù)據(jù)中的位圖信息結(jié)構(gòu)來獲取、顯示圖像數(shù)據(jù)了。下面的函數(shù)實(shí)現(xiàn)了,該函數(shù)的實(shí)現(xiàn)代碼如下所示: 2、 灰度位圖數(shù)據(jù)的存儲 為了將圖像處理后所得到的像素值保存起來,我們重載了文檔類的OnSaveDocument()函數(shù),這樣用戶在點(diǎn)擊Save或SaveAs子菜單后程序自動調(diào)用該函數(shù),實(shí)現(xiàn)圖像數(shù)據(jù)的存儲。該函數(shù)的具體實(shí)現(xiàn)如下:二、 調(diào)色板的操作通過上面的操作,我們已經(jīng)可以獲取圖像中的數(shù)據(jù)了,現(xiàn)在的又一個問題是如何在窗口中顯示出圖像數(shù)據(jù)。灰度圖像要正確顯示,必須實(shí)現(xiàn)邏輯調(diào) 色板和系統(tǒng)調(diào)色板。首先我們介紹一下,該結(jié)構(gòu)定義如下:可以通過CDC:SelectPalette()、

8、CDC:RealizePalette()或相應(yīng)的API函數(shù)來實(shí)現(xiàn)上述的兩個步驟。在實(shí)現(xiàn)調(diào)色板的過程中,通過在主框架類中處理Windows定義的 消息WM_QUERYNEWPALETTE 、WM_PALETTECHANGED及視圖類中處理自定義消息WM_DOREALIZE(該消息在主框架窗口定義如下:#define WM_REALIZEPAL (WM_USER+101))來實(shí)現(xiàn)調(diào)色板的操作。當(dāng)系統(tǒng)需要處理調(diào)色板的變化時,將向程序的主窗口發(fā)送WM_QUERYNEWPALETTE 、WM_PALETTECHANGED,例如當(dāng)某一窗口即將激活時,主框架窗口將收到WM_QUERYNEWPALETTE消息

9、,通知該窗口將要收到輸入 焦點(diǎn),給它一次機(jī)會實(shí)現(xiàn)其自身的邏輯調(diào)色板;當(dāng)系統(tǒng)調(diào)色板改變后,主框架窗口將收到WM_PALETTECHANGED消息,通知其它窗口系統(tǒng)調(diào)色板已經(jīng) 改變,此時每一窗口都應(yīng)該實(shí)現(xiàn)其邏輯調(diào)色板,重畫客戶區(qū)。 由于上述的調(diào)色板變更消息是發(fā)往主框架窗口的,所以我們只能在主窗口中響應(yīng)這兩個消息,然后由主框架窗口通知各個視窗,使得程序激活時能自動裝載自己的調(diào) 色板。我們定義的用戶消息WM_REALIZEPAL用于主框架窗口通知視窗它已經(jīng)收到調(diào)色板變更消息,視窗應(yīng)該協(xié)調(diào)其調(diào)色板。下面我們給出了各個消息的 響應(yīng)處理函數(shù)的具體實(shí)現(xiàn)代碼和注釋: 注:讀者可以從后面的顯示部分的實(shí)現(xiàn)看出我們在

10、顯示時實(shí)現(xiàn)了邏輯調(diào)色板。上述的處理相對來說比較繁瑣復(fù)雜,可能對于初學(xué)者來說也比較難于理解,所以這 樣作的好處是在取灰度位圖時可以不再考慮文件中的顏色表信息,提高了文件讀取速度,筆者在開發(fā)一個基于機(jī)器泳醯南钅渴輩捎玫木褪欽庵址椒 吮冉下獾男 ?/p三、 圖像的顯示顯示DIB位圖數(shù)據(jù)可以通過設(shè)備上下文CDC對象的成員函數(shù)CDC:Bitblt()或CDC:StretchBlt()來實(shí)現(xiàn),也可以通過 API函數(shù)SetDIBBitsToDevice()或StretchDIBBits()來實(shí)現(xiàn),函數(shù)中具體所用到的各個參數(shù)的意義可以參考 MSDN。其中StretchDIBBits()和CDC:Stretch

11、Blt()可以將圖像進(jìn)行放大和縮小顯示。當(dāng)從文檔中裝入位圖文件時, CDIBView類的OnInitialUpdate函數(shù)將被調(diào)用,因此可以在該函數(shù)中實(shí)現(xiàn)對視圖尺寸的設(shè)置,用于正確的顯示位圖,然后就可以在視圖類的 OnDraw()函數(shù)中正確的顯示位圖了。這兩個函數(shù)的具體實(shí)現(xiàn)代碼分別如下所示: 四、 小結(jié) 在本期講座里我們主要介紹了如何操作灰度位圖,它具有較強(qiáng)的代表性,同時為后續(xù)的圖像處理編程的學(xué)習(xí)作了必要的準(zhǔn)備工作,經(jīng)過學(xué)習(xí),對于如何操作其它類型的BMP格式的圖像文件,可以達(dá)到舉一反三的作用。 VC數(shù)字圖像處理編程講座之四 BMP圖像顯示的特效操作上期講座中我們主要講述了BMP圖像數(shù)據(jù)的存取、

12、圖像的顯示和調(diào)色板的操作等內(nèi)容,在上面的學(xué)習(xí)基礎(chǔ)上,我們可以進(jìn)一步深化,學(xué)習(xí)并掌握圖像特效顯示 技術(shù)。有了這種技術(shù),可以用來在今后的項(xiàng)目開發(fā)中美化我們的軟件界面,提高軟件的視覺效果。在如今的商業(yè)軟件中,幾乎每一幅圖像的顯示都采用了圖像特效顯 示,例如讀者比較熟悉的Windows的屏幕保護(hù)程序就采用了各種各樣的圖像特效顯示,使人感到眼花繚亂和耳目一新。專業(yè)圖像處理軟件更是提供了豐富的顯示方式供用戶使用,可以方便的在程序中實(shí)現(xiàn)圖像的特效顯示,如PhotoShop 、Authorware等。本節(jié)主要介紹如何實(shí)現(xiàn)圖像的浮雕、雕刻、百頁窗、旋轉(zhuǎn)、掃描、柵條、馬賽克、和漸顯漸隱顯示等效果。通過這期講座的學(xué)

13、習(xí),讀者朋友們也可以自己動手制作擁有特效顯示效果的軟件了。圖像的顯示我們講過主要有BitBlt()、SetDIBitsToDevice()和StretchDIBits()等函數(shù)。需要讀者注意的是,在 特效顯示時,并不是每個顯示函數(shù)都適宜,BitBlt()函數(shù)主要是用來顯示設(shè)備相關(guān)位圖(DDB),SetDIBitsToDevice()和 StretchDIBits()兩個函數(shù)用來顯示設(shè)備無關(guān)位圖(DIB)。由于我們講座里處理的是設(shè)備無關(guān)位圖,所以我們主要關(guān)心的是后兩個函數(shù)的應(yīng)用, 其中SetDIBitsToDevice()使用起來較死板,遠(yuǎn)不如 StretchDIBits()用的靈活,并且對大多

14、數(shù)的特效顯示無能為力,所以為了實(shí)現(xiàn)圖像的特效顯示效果,需要使用StretchDIBits ()函數(shù)來顯示圖像,具體什么原因,我想可能是微軟在實(shí)現(xiàn)這些函數(shù)時使用的方法不同吧。這些函數(shù)如何使用,各個參數(shù)的含義,可以參考微軟的MSDN。實(shí)現(xiàn)圖像的特殊效果的顯示的基本思路是要么是操作圖像的像素,要么是對圖像分塊按一定的方向或次序,分階段的顯示或擦除對應(yīng)的圖像塊。對于第二種顯示 的思路,其中的要點(diǎn)是:1.劃分圖像塊;2.確定圖像塊的操作次序;3.顯示或清除對應(yīng)的圖像塊;4.在兩個連續(xù)顯示的圖像塊之間插入一個固定的延遲。其 中圖像塊的劃分決定了圖像的顯示方式,圖像塊的顯示順序決定了顯示的方向和細(xì)分的依據(jù)。

15、不同的效果決定了不同的分塊方法和顯示次序,我們將在后面的各種特 效顯示中介紹如何分塊和決定次序。為了使圖像的顯示過程明顯的表現(xiàn)出來,實(shí)現(xiàn)顯示的特效,就需要在圖像塊的依此顯示中插入固定的延遲。也許讀者朋友會想到 利用sleep()函數(shù)或用Settime()來實(shí)現(xiàn)延遲,由于Windows是個基于消息的多任務(wù)操作系統(tǒng),這些方法所產(chǎn)生的延遲時間對于圖像的顯示來 說是不精確的,為了實(shí)現(xiàn)與機(jī)器無關(guān)的更精確的時間延遲,可以采用timeGetTime()函數(shù)來產(chǎn)生微秒級的延遲。使用這個函數(shù)時為了編譯不產(chǎn)生錯誤, 要在連接設(shè)置中引入Winmm.lib庫,并要包含頭文件Mmsystem.h。這里我們首先給出一個延

16、遲函數(shù),它用來實(shí)現(xiàn)固定時間的延遲:void DelayTime(DWORD time)DWORD BeginTime ,EndTime;BeginTime=timeGetTime();/得到當(dāng)前的系統(tǒng)時間、單位為微秒;doEndTime=timeGetTime();/再次得到當(dāng)前的系統(tǒng)時間;while(EndTime-BeginTime)一、操作位圖的像素實(shí)現(xiàn)顯示的特效我們首先介紹直接操作圖像中的像素的灰度值來實(shí)現(xiàn)圖像顯示的特效、這里我們主要介紹如何實(shí)現(xiàn)圖像的浮雕和雕刻效果。經(jīng)??措娨暤呐笥褌儾恢⒁獾?jīng)] 有,有些電視連續(xù)劇在每集片頭或片尾部分都有顯示一些特殊效果的圖像,比如前一陣子中央一套放

17、的長征和康熙王朝,這些特效稱為圖像的浮雕效果和圖 像的雕刻效果,經(jīng)過這些特效處理后的圖像增強(qiáng)了觀眾們的視覺效果,它們看上去仿佛是使用3D技術(shù)作的,這也許就是為什么這種技術(shù)那么流行的原因吧。其實(shí), 我們完全可以用一些簡單的數(shù)字圖像處理算法來實(shí)現(xiàn)這些看似復(fù)雜高深的顯示效果。下面以一個標(biāo)準(zhǔn)的Lena灰度圖像為原圖,給出了處理后的效果圖,同時給出 了VC開發(fā)平臺上的部分實(shí)現(xiàn)源代碼。1浮雕圖像浮雕圖象效果是指圖像的前景前向凸出背景。所謂的浮雕概念是指標(biāo)繪圖像上的一個像素和它左上方的那個像素之間差值的一種處理過程,為了使圖像保持一定 的亮度并呈現(xiàn)灰色,我在處理過程中為這個差值加了一個數(shù)值為128的常量。需

18、要讀者注意的是,當(dāng)設(shè)置一個像素值的時候,它和它左上方的像素都要被用到,為 了避免用到已經(jīng)設(shè)置過的像素,應(yīng)該從圖像的右下方的像素開始處理,下面是實(shí)現(xiàn)的源代碼:void CDibView:OnFDImage() /產(chǎn)生浮雕效果圖函數(shù)HANDLE data1handle;/用來存放圖像數(shù)據(jù)的句柄;LPBITMAPINFOHEADER lpBi;/圖像的信息頭結(jié)構(gòu);CDibDoc *pDoc=GetDocument();/得到文擋指針;HDIB hdib;/用來存放圖像數(shù)據(jù)的句柄;unsigned char *pData;/指向原始圖像數(shù)據(jù)的指針;unsigned char *data;/指向處理后圖

19、像數(shù)據(jù)的指針;hdib=pDoc-m_hDIB;/拷貝存放已經(jīng)讀取的圖像文件數(shù)據(jù)句柄;lpBi=(LPBITMAPINFOHEADER)GlobalLock(HGLOBAL)hdib);/獲取圖像信息頭pData=(unsigned char*)FindDIBBits(LPSTR)lpBi);/FindDIBBits是我定義的一個函數(shù)、根據(jù)圖像的結(jié)構(gòu)得到位圖的灰度值數(shù)據(jù)、pDoc-SetModifiedFlag(TRUE);/設(shè)置文檔修改標(biāo)志為真、為后續(xù)的修改存盤作準(zhǔn)備;data1handle=GlobalAlloc(GMEM_SHARE,WIDTHBYTES(lpBi-biWidth*8)*

20、lpBi-biHeight);/聲明一個緩沖區(qū)用來暫存處理后的圖像數(shù)據(jù);data=(unsigned char*)GlobalLock(HGLOBAL)data1handle);/得到該緩沖區(qū)的指針;AfxGetApp()-BeginWaitCursor();int i,j,buf;for( i=lpBi-biHeight; i=2; i )/從圖像右下角開始對圖像的各個像素進(jìn)行浮雕處理;for( j=lpBi-biWidth; j=2; j )/浮雕處理buf=*(pData+(lpBi-biHeight-i)*WIDTHBYTES(lpBi-biWidth*8)+j)-*(pData+(l

21、pBi-biHeight-i+1)*WIDTHBYTES(lpBi-biWidth*8)+j-1)+128;if(buf255) buf=255;if(bufbiHeight-i)*WIDTHBYTES(lpBi-biWidth*8)+j)=(BYTE)buf;for( j=0; jbiHeight; j+)for( i=0; ibiWidth; i+)/重新寫回原始圖像的數(shù)據(jù)緩沖區(qū);*(pData+i*WIDTHBYTES(lpBi-biWidth*8)+j)=*(data+i*WIDTHBYTES(lpBi-biWidth*8)+j);AfxGetApp()-EndWaitCursor()

22、;pDoc-m_hDIB =hdib/將處理過的圖像數(shù)據(jù)寫回pDoc中的圖像緩沖區(qū);GlobalUnlock(HGLOBAL)hdib);/解鎖、釋放緩沖區(qū);GlobalUnlock(HGLOBAL)data1handle);GlobalFree(HGLOBAL)hdib);GlobalFree(HGLOBAL)data1handle);Invalidate(TRUE);/顯示圖像2雕刻圖像上面講述了通過求一個像素和它左上方像素之間的差值并加上一個常數(shù)的方法生成浮雕效果的灰度圖像,雕刻圖像與之相反,它是通過取一個像素和它右下方的 像素之間的差值并加上一個常數(shù),這里我也取128,經(jīng)過這樣處理,就

23、可以得到雕刻圖像,這時候圖像的前景凹陷進(jìn)背景之中。同樣需要讀者注意的是為了避免重 復(fù)使用處理過的圖像像素,處理圖像時要從圖像的左上方的像素開始處理。實(shí)現(xiàn)代碼如下:void CDibView:OnDKImage()/ TOD Add your command handler code hereHANDLE data1handle;/這里的內(nèi)部變量與前面的含義一致、這里不再贅述;LPBITMAPINFOHEADER lpBi;CDibDoc *pDoc=GetDocument();HDIB hdib;unsigned char *pData;unsigned char *data;hdib=pDo

24、c-m_hDIB;/拷貝圖像數(shù)據(jù)的句柄;lpBi=(LPBITMAPINFOHEADER)GlobalLock(HGLOBAL)hdib);pData=(unsigned char*)FindDIBBits(LPSTR)lpBi);pDoc-SetModifiedFlag(TRUE);data1handle=GlobalAlloc(GMEM_SHARE,WIDTHBYTES(lpBi-biWidth*8)*lpBi-biHeight);/申請緩沖區(qū);data=(unsigned char*)GlobalLock(HGLOBAL)data1handle);/得到新的緩沖去的指針;AfxGetAp

25、p()-BeginWaitCursor();int i,j,buf;for( i=0;ibiHeight-2; i+)/對圖像的各個像素循環(huán)進(jìn)行雕刻處理;for( j=0;jbiWidth-2; j+)buf=*(pData+(lpBi-biHeight-i)*WIDTHBYTES(lpBi-biWidth*8)+ j)-*(pData+(lpBi-biHeight-i-1)*WIDTHBYTES(lpBi-biWidth*8)+j+1)+128; /雕刻處理;if(buf255) buf=255;if(bufbiHeight-i)*WIDTHBYTES(lpBi-biWidth*8)+j)=

26、(BYTE)buf;for( j=0; jbiHeight; j+) for( i=0; ibiWidth; i+)/重新將處理后的圖像數(shù)據(jù)寫入原始的圖像緩沖區(qū)內(nèi);*(pData+i*WIDTHBYTES(lpBi- biWidth*8)+j)=*(data+i*WIDTHBYTES(lpBi-biWidth*8)+j);pDoc-m_hDIB =hdib/將處理過的圖像數(shù)據(jù)寫回pDoc中的圖像緩沖區(qū);GlobalUnlock(HGLOBAL)hdib);/解鎖、釋放緩沖區(qū);GlobalUnlock(HGLOBAL)data1handle);GlobalFree(HGLOBAL)hdib);G

27、lobalFree(HGLOBAL)data1handle);Invalidate(TRUE);/顯示圖像3圖像的旋轉(zhuǎn)根據(jù)圖像像素的位置來調(diào)節(jié)該位置的灰度可以實(shí)現(xiàn)許多顯示的特效,例如圖像的鏡像、翻轉(zhuǎn)等。灰度圖像旋轉(zhuǎn)就是根據(jù)這一個思想實(shí)現(xiàn)的,它是指把定義的圖像 繞某一點(diǎn)以逆時針或順時針方向旋轉(zhuǎn)一定的角度,通常是指繞圖像的中心以逆時針方向旋轉(zhuǎn)。首先根據(jù)旋轉(zhuǎn)的角度、圖像對角線的長度計(jì)算旋轉(zhuǎn)后的圖像的最大寬 度、高度,根據(jù)旋轉(zhuǎn)后圖象最大的寬度、高度生成新的緩沖區(qū),假設(shè)圖像的左上角為(left, top),右下角為(right, bottom),則圖像上任意點(diǎn)(x, y)繞其中心(xcenter, yc

28、enter)逆時針旋轉(zhuǎn)angle角度后,新的坐標(biāo)位置(x1, y1)的計(jì)算公式為:xcenter = (width+1)/2+left;ycenter = (height+1)/2+top;x1 = (x-xcenter) cos - (y - ycenter) sin+xcenter;y1 = (x-xcenter) sin+ (y- ycenter) cos+ ycenter;與圖像的鏡像變換相類似,下一步就是把原圖中的(x,y)處象素的灰度值讀入新緩沖區(qū)的(x1,y1)點(diǎn)處。注意在新緩沖區(qū)中與原圖沒有對應(yīng)的象素點(diǎn)的值用白色或指定的灰度代替。二、圖像的分塊顯示和清除1 圖像的掃描顯示和清除

29、掃描顯示圖像是最基本的特效顯示方法,它表現(xiàn)為圖像一行行(或一列列)地顯示出來或從屏幕上清除掉,有種大戲院種的拉幕效果。根據(jù)掃描的方向的不同, 可以分為上、下、左、右、水平平分和垂直平分等六種掃描。這里以向下移動為例,分別介紹顯示和清除的實(shí)現(xiàn)。其余的掃描效果可以依次類推。向下掃描顯示的實(shí) 現(xiàn)方法是:從圖像的底部開始將圖像一行一行的復(fù)制到目標(biāo)區(qū)域的頂部。每復(fù)制一行后,復(fù)制的行數(shù)便要增加一行,并加上一些延遲;向下移動清除的實(shí)現(xiàn)方法是圖 像向下移動顯示,并在顯示區(qū)域的上部畫不斷增高的矩形。1)掃描顯示的代碼:CdibView:OnImageDownScan()CDibDoc *pDoc=GetDocu

30、ment();HDIB hdib;CClientDC pDC(this);hdib=pDoc-m_hDIB;/獲取圖像數(shù)據(jù)句柄;BITMAPINFOHEADER *lpDIBHdr;/位圖信息頭結(jié)構(gòu)指針;BYTE *lpDIBBits;/指向位圖像素灰度值的指針;HDC hDC=pDC.GetSafeHdc();/獲取當(dāng)前設(shè)備上下文的句柄;lpDIBHdr=( BITMAPINFOHEADER *)GlobalLock(hdib);/得到圖像的位圖頭信息;lpDIBBits=(BYTE*)lpDIBHdr+sizeof(BITMAPINFOHEADER)+256*sizeof(RGBQUAD)

31、;/獲取指向圖像像素值;SetStretchBltMode(hDC,COLORONCOLOR);/顯示圖像;for(int i=0;ibiHeight;i+) /每次循環(huán)顯示圖象的0到i行數(shù)據(jù);SetDIBitsToDevice (hDC,0,0,lpDIBHdr-biWidth, lpDIBHdr-biHeight,0, 0,0, i,lpDIBBits,(LPBITMAPINFO)lpDIBHdr,DIB_RGB_COLORS);DelayTime(50);/延遲;GlobalUnlock(hdib);return;2)清除代碼:./由于篇幅的限制,省略了與上面的相同代碼Cbrush br

32、ush(crWhite);/定義一個白色的刷子;Cbrush *oldbrush=pDC-SelectObject(&brush);for(int i=0;i biHeight ;i+)/每次循環(huán)將目標(biāo)區(qū)域中的0到i行刷成白色;pDC-Rectangle(0,0,lpDIBHdr-biWidth,lpDIBHdr-biHeight);DelayTime(50);.2 百頁窗效果所謂百頁窗顯示效果,就如同關(guān)閉和開啟百頁窗一樣,圖像被分為一條條或一列列地分別顯示或清除掉,根據(jù)顯示時以行或列為單位可以將該效果分為垂直或水 平兩種方式。以垂直百頁窗為例來說明如何實(shí)現(xiàn)這種特效顯示。實(shí)現(xiàn)垂直百頁窗顯示時,

33、需要將圖像垂直等分為n部分由上向下掃描顯示,其中每一部分包括m個 條、這個n可以根據(jù)具體應(yīng)用時的需要來決定、m既為圖像的高度除n。掃描顯示時,依照差值進(jìn)行掃描顯示,即第k次顯示k-1、k*m-1、.k*n -1條掃描線。同樣,垂直百頁窗清除的實(shí)現(xiàn)與垂直百頁窗的顯示相似,不同的是將繪制位圖換成畫矩形而已。在下面的例子中,我將圖像的分成8份。.int m=8;int n=lpDIBHdr-biHeight/m;/圖像的高度能夠整除8;for(int l=1;lbiWidth,1,0, lpDIBHdr-biHeight-4*k-l+1,lpDIBHdr-biWidth,1,lpDIBBits,(L

34、PBITMAPINFO)lpDIBHdr,DIB_RGB_COLORS,SRCCOPY);/juanlianxiaoguoDelayTime(50);.3.柵條顯示特效柵條特效是移動特效的復(fù)雜組合,可以分為垂直柵條和水平柵條兩類。它的基本思想是將圖像分為垂直或水平的的小條,奇數(shù)條向上或向左顯示/清除,偶數(shù)條向下或向右顯示/清除。當(dāng)然也可以規(guī)定進(jìn)行相反的方向顯示/清除。下面的代碼是實(shí)現(xiàn)垂直柵條的例子:.int m=8;for(int i=0;ibiHeight;i+)for(int j=0;jbiWidth;j+=m)/向下顯示偶數(shù)條;StretchDIBits (hDC,j,0,m,i,j,l

35、pDIBHdr-biHeight-i,m,i,lpDIBBits,(LPBITMAPINFO)lpDIBHdr,DIB_RGB_COLORS,SRCCOPY);/juanlianxiaoguoj=j+m;/向上顯示奇數(shù)條;StretchDIBits (hDC,j,lpDIBHdr-biHeight-i,m,i,j,0,m,i,lpDIBBits,(LPBITMAPINFO)lpDIBHdr,DIB_RGB_COLORS,SRCCOPY);/DelayTime(20);.4.馬賽克效果馬賽克顯示是指圖像被分成許多的小塊,它們以隨機(jī)的次序顯示出來,直到圖像顯示完畢。實(shí)現(xiàn)馬賽克的效果主要解決的問題是

36、如何定義顯示隨機(jī)序列的小方 塊,這個問題的解決可以在定義過小方塊的基礎(chǔ)上,用一個數(shù)組來記錄各個方塊的左上角的坐標(biāo)的位置。顯示圖像過程中,產(chǎn)生一個隨機(jī)數(shù)來挑選即將顯示的小方 塊,顯示后將該方塊的位置坐標(biāo)從數(shù)組中剔除。清除過程與之相仿。剔除顯示過的方塊的位置坐標(biāo)的方法是將該數(shù)組中的最后的一個點(diǎn)的坐標(biāo)拷貝到當(dāng)前位置,然后 刪除數(shù)組中的最后點(diǎn)的坐標(biāo),經(jīng)過實(shí)現(xiàn)發(fā)現(xiàn)這樣處理有時顯示的圖像是不完整的,分析其原因是生成隨機(jī)數(shù)的過程有舍入溢出誤差。讀者可以采用其它的辦法解決這 個問題,例如可以生成固定的隨機(jī)數(shù)組或采用一個動態(tài)的數(shù)組來跟蹤未顯示的圖像方塊的坐標(biāo)等方法。.int m,n;int RectSize=6

37、0;/方塊的寬、高尺寸為60個像素;if(lpDIBHdr-biWidth%RectSize!=0)/得到圖像水平方塊的個數(shù);m= lpDIBHdr-biWidth/RectSize+1;elsem= lpDIBHdr-biWidth/RectSize;if(lpDIBHdr-biHeight%RectSize!=0)/得到圖像垂直方塊的個數(shù);n= lpDIBHdr-biHeight/RectSize+1;elsen=lpDIBHdr-biHeight/RectSize;POINT *point=new POINTn*m;/申請一個數(shù)組用來記錄各個方塊的左上角的坐標(biāo);POINT point1;

38、for(int a=0;afor(int b=0;bpoint1.x=a*RectSize;point1.y=b*RectSize;*(point+a*b+b)=point1;/開始隨機(jī)的顯示各個小方塊;double fMax=RAND_MAX;/定義Rand()函數(shù)的最大值;for(int k=m*n-1;k=0;k )int c=(int)(double)(m*n)*rand()/fMax);int mx=pointc.x;int my=pointc.y;/顯示對應(yīng)的圖像的小塊;StretchDIBits (hDC,mx,my,RectSize,RectSize,mx,lpDIBHdr-b

39、iHeight-my,RectSize,RectSize,lpDIBBits,(LPBITMAPINFO)lpDIBHdr,DIB_RGB_COLORS,SRCCOPY);pointc.x=pointk.x;pointc.y=pointk.y;DelayTime(50);.5圖像的淡入淡出效果圖像的淡入淡出的顯示效果被廣泛的應(yīng)用在多媒體娛樂軟件中,是一種特別重要的特效顯示方法。淡入就是將顯示圖像的目標(biāo)區(qū)域由本色逐漸過度的圖像中的各 個像素點(diǎn)的顏色;淡出就是由顯示的圖像逐漸過度到目標(biāo)區(qū)域的本色。實(shí)現(xiàn)圖像的淡入淡出有兩種辦法:一是均勻的改變圖像的調(diào)色板中的顏色索引值;另一種方法 是改變圖像像素的灰

40、度值。第一種方法實(shí)現(xiàn)起來比較繁瑣,第二種方法就比較簡單。下面是我們采用第二種方法實(shí)現(xiàn)圖像淡入效果的代碼:./申請一個與圖像緩沖區(qū)相同大小的內(nèi)存;hdibcopy=(HDIB)GlobalAlloc(GMEM_SHARE,lpDIBHdr-biWidth*lpDIBHdr-biHeight);lpbits=(BYTE*)GlobalLock(hdibcopy);/將緩沖區(qū)的數(shù)據(jù)初始化;for(int k=0;kbiWidth*lpDIBHdr-biHeight;k+)*(lpbits+k)=(BYTE)255;/顯示最初的圖像為白色StretchDIBits (hDC,0,0,lpDIBHdr-

41、biWidth,lpDIBHdr-biHeight,0,0,lpDIBHdr-biWidth,lpDIBHdr-biHeight,lpbits,(LPBITMAPINFO)lpDIBHdr,DIB_RGB_COLORS,SRCCOPY);/布爾變量end用來標(biāo)志何時淡入處理結(jié)束;BOOL end=false;while(!end) int a=0;for(int k=0;kbiWidth*lpDIBHdr-biHeight;k+)/判斷是否待顯示的像素的灰度值已經(jīng)小于原始圖像對應(yīng)點(diǎn)的灰度值,如是則計(jì)數(shù);if(*(lpbits+k)biWidth,lpDIBHdr-biHeight,0,0,lp

42、DIBHdr-biWidth,lpDIBHdr-biHeight,lpbits,(LPBITMAPINFO)lpDIBHdr,DIB_RGB_COLORS,SRCCOPY);/如果所有的點(diǎn)的灰度值的都小于或等于原始圖像的像素點(diǎn)的灰度值,則認(rèn)為圖像的淡入處理結(jié)束。if(a=lpDIBHdr-biWidth*lpDIBHdr-biHeight)end=true; DelayTime(50);.本文上面的內(nèi)容介紹了幾種圖像的特殊顯示效果,代碼在Windows2000和Visual C+6.0編程環(huán)境下編譯通過,運(yùn)行正常,處理達(dá)到了預(yù)期的效果。讀者可以將上面介紹的顯示圖像的函數(shù)和處理思路結(jié)合起來,實(shí)現(xiàn)

43、更多效果。VC編程實(shí)現(xiàn)灰度圖像與彩色圖像的相互轉(zhuǎn)換PhotoShop的圖像處理功能很強(qiáng),其中有一個功能是將灰度圖像轉(zhuǎn)換為彩色圖像,數(shù)字圖像處理中,也經(jīng)常要遇到灰度圖像與彩色圖像相互轉(zhuǎn)換的問題,如何自己解決這個問題,值得大家探討,現(xiàn)將我解決這類問題的方法陳述如下:工程應(yīng)用中經(jīng)常要遇到需要把彩色圖像到灰度圖像的變換的問題,采集卡過來的圖像為彩色圖像,為加快處理速度,要把彩色圖像轉(zhuǎn)換為黑白圖象,這個問題比 較好解決,一般情況下彩色圖像每個像素用三個字節(jié)表示,每個字節(jié)對應(yīng)著R、G、B分量的亮度(紅、綠、藍(lán)),轉(zhuǎn)換后的黑白圖像的一個像素用一個字節(jié)表示該 點(diǎn)的灰度值,它的值在0255之間,數(shù)值越大,該點(diǎn)越

44、白,既越亮,越小則越黑。轉(zhuǎn)換公式為Gray(i,j)=0.11*R(i,j)+ 0.59*G(i,j)+0.3*B(i,j),其中Gray(i,j)為轉(zhuǎn)換后的黑白圖像在(i,j)點(diǎn)處的灰度值,我們可以觀察該式,其中綠色所占的 比重最大,所以轉(zhuǎn)換時可以直接使用G值作為轉(zhuǎn)換后的灰度。至于灰度圖像轉(zhuǎn)換為彩色圖像,技術(shù)上稱為灰度圖像的偽彩色處理,這是一種視覺效果明顯而技術(shù)又不是很復(fù)雜的圖像增強(qiáng)技術(shù)?;叶葓D像中,如果相鄰像素點(diǎn) 的灰度相差不大,但包含了豐富的信息的話,人眼則無法從圖像中提取相應(yīng)的信息,因?yàn)槿搜鄯直婊叶鹊哪芰懿?,一般只有幾十個數(shù)量級,但是人眼對彩色信號的 分辨率卻很強(qiáng),這樣將黑白圖像轉(zhuǎn)換

45、為彩色圖像人眼可以提取更多的信息量。在轉(zhuǎn)換過程中,經(jīng)常采用的技術(shù)是灰度級-彩色變換,意思就是對黑白圖像上的每一個 像素點(diǎn),取得該點(diǎn)的灰度值并送入三個通道經(jīng)過實(shí)施不同的變換,產(chǎn)生相應(yīng)的R、G、B的亮度值,即所求彩色圖像對應(yīng)像素點(diǎn)的彩色值,具體變換公式很多,我采 用的是最常用的一種,變換曲線圖如下:上圖中,三個圖分別代表了三個變換通道,R、G、B指的是變換后對應(yīng)點(diǎn)的R、G、B分量值,L指的是各個分量的最大值為255,G(x,y)為相應(yīng)點(diǎn)的灰 度值。理論上就這些,下面是我用VC實(shí)現(xiàn)的源代碼,圖一為我的灰度位圖,圖二為偽彩色處理后的結(jié)果圖。我這個實(shí)現(xiàn)函數(shù)中是如何得到灰度位圖的數(shù)據(jù)的就不多 講了,有興趣

46、的朋友可參考我在天極網(wǎng)上九月十號發(fā)表的VC灰度位圖處理一文,那里應(yīng)該講的很清楚了。需要讀者注意的是彩色圖像中每個象素中的三個字節(jié) 分別代表的分量,第一個字節(jié)為B,第二個為G值、最后一個為R值,這個順序不要搞錯了。代碼實(shí)現(xiàn)如下:void CDibView:OnMenuchange() file:/圖像轉(zhuǎn)換實(shí)現(xiàn)函數(shù)/ TOD Add your command handler code hereHANDLE data1handle;LPBITMAPINFOHEADER lpBi;BITMAPINFO *m_pBMI;CDibDoc *pDoc=GetDocument();HDIB hdib;unsi

47、gned char *hData;unsigned char *data;hdib=pDoc-GetHDIB();/得到位圖數(shù)據(jù)的句柄,其中包含圖像信息頭BeginWaitCursor();lpBi=(LPBITMAPINFOHEADER)GlobalLock(HGLOBAL)hdib);hData=(unsigned char*)FindDIBBits(LPSTR)lpBi);m_pBMI=new BITMAPINFO;/生成彩色圖像的信息頭m_pBMI-bmiHeader.biBitCount=24;m_pBMI-bmiHeader.biClrImportant=0;m_pBMI-bmiH

48、eader.biClrUsed=0;m_pBMI-bmiHeader.biCompression=BI_RGB;m_pBMI-bmiHeader.biHeight=lpBi-biHeight;m_pBMI-bmiHeader.biWidth=lpBi-biWidth;m_pBMI-bmiHeader.biPlanes=1;m_pBMI-bmiHeader.biSize=sizeof(BITMAPINFOHEADER);m_pBMI-bmiHeader.biXPelsPerMeter=0;m_pBMI-bmiHeader.biYPelsPerMeter=0;m_pBMI-bmiHeader.bi

49、SizeImage=WIDTHBYTES(lpBi-biWidth*8)*lpBi-biHeight*3;file:/data=hData;int R,G,B,i,j;data1handle=GlobalAlloc(GMEM_SHARE,WIDTHBYTES(lpBi-biWidth*8)*lpBi-biHeight*3);file:/生成存儲彩色圖象數(shù)據(jù)的緩沖區(qū)data=(unsigned char*)GlobalLock(HGLOBAL)data1handle);for(i=0;ibiHeight;i+)/實(shí)現(xiàn)灰度到彩色變換for(j=0;jbiWidth*8);j+)if(*(hData

50、+i*WIDTHBYTES(lpBi-biWidth*8)+j)biWidth*8)+j);B=255;if(*(hData+i*WIDTHBYTES(lpBi-biWidth*8)+j)64& *(hData+i*WIDTHBYTES(lpBi-biWidth*8)+j)biWidth*8)+j);if(*(hData+i*WIDTHBYTES(lpBi-biWidth*8)+j)128& *(hData+i*WIDTHBYTES(lpBi-biWidth*8)+j)biWidth*8)+j)-128);G=255;B=0;if(*(hData+i*WIDTHBYTES(lpBi-biWid

51、th*8)+j)192& *(hData+i*WIDTHBYTES(lpBi-biWidth*8)+j)biWidth*8)+j);B=0;file:/將生成的R、G、B分量存入目標(biāo)緩沖區(qū)*(data+i*WIDTHBYTES(lpBi-biWidth*8)*3+j*3)=B;*(data+i*WIDTHBYTES(lpBi-biWidth*8)*3+j*3+1)=G;*(data+i*WIDTHBYTES(lpBi-biWidth*8)*3+j*3+2)=R;GlobalUnlock(HGLOBAL)hdib);GlobalUnlock(data1handle);EndWaitCursor(

52、);CClientDC pDC(this);file:/顯示真彩色圖像StretchDIBits(pDC.GetSafeHdc(),0,0,lpBi-biWidth,lpBi-biHeight,0,0,lpBi-biWidth, lpBi-biHeight,data,m_pBMI,DIB_RGB_COLORS,SRCCOPY);delete m_pBMI;BMP圖像操作的補(bǔ)充篇上一講中我們介紹了圖像特效顯示操作的實(shí)現(xiàn)方法,如隨機(jī)顯示效果、馬賽克效果、拉幕顯示效果等,由于篇幅的限制,還有許多效果沒有介紹;本期講座將接著上一講的內(nèi)容,繼續(xù)介紹一些圖像特效顯示效果。另 外,我們前面的學(xué)習(xí)都是針對現(xiàn)成的BMP圖像,在實(shí)際工作學(xué)習(xí)中,絕大部分處理圖像過程都是在一個系統(tǒng)環(huán)境中,也就是說需要和圖像數(shù)據(jù)的獲取設(shè)備直接打交 道,一般情況下,計(jì)算機(jī)圖像處理系統(tǒng)從系統(tǒng)層次上可分為高、中、低檔三個層次,目前比較普及的是低檔次的系統(tǒng),

溫馨提示

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

最新文檔

評論

0/150

提交評論