【正文】
周圍的顏色(范圍大小以馬賽克大小而定,本文以邊長為5個(gè)點(diǎn)的小方塊為例),將每點(diǎn)的色分解為三元色后求其平均值,然后把該色寫回到這一小正方形區(qū)域即可。原代碼如下:Private Sub Command9_Click() For i=2 To Picture1. ScaleW idth2 Step 5 For j=2 To Picture1. ScaleHeight2 Step 5 r1=0: g1=0: b1=0 For k=i2 To i+2 For l=j2 To j+2 col=Picture1. Point(k, l) r1=r1+colMod 256 g1=g1+col\256Mod 256 b1=b1+col\256 \256 Next1 Nextk r=r1 /25 g=g1 /25 b=b1 /25 For k=i2 To i+2 For l=j2 To j+2 Picture2. PSet(k, l),RGB(r, g, b) Next1 NextkNext jNext iEnd Sub3 結(jié)束語本文介紹了用VB實(shí)現(xiàn)圖像處理的幾類常見方法,由于篇幅限制有些圖像處理沒有介紹到,如:模糊、銳化、增減對比度、變亮、變暗、增減飲和度等,要實(shí)現(xiàn)對圖像的這些處理,只要明白這些概念的含義,用類似前面介紹的“取色寫點(diǎn)”的方法是完全可以實(shí)現(xiàn)的。只是處理速度明顯的要比現(xiàn)有的圖像處理軟件要慢。參考文獻(xiàn)[ 1 ]劉煥軍,2003, 16(12): 17.[ 2 ]孫其民, 14(10): 1796.用混合編程開發(fā)圖像處理系統(tǒng)Developing Image Processing System with Hybrid Language【摘 要】 提出了一種用VB與VC混合編程開發(fā)圖像處理系統(tǒng)的方法。簡要介紹了VB中調(diào)用DLL的知識。闡述了在VB中通過調(diào)用API函數(shù)快速獲取圖像像素信息和顯示圖像的方法。最后論述了如何在VC中編寫用作圖像處理的DLL以及在VB中調(diào)用這個(gè)DLL?!娟P(guān)鍵詞】 圖像處理,混合編程,動(dòng)態(tài)鏈接庫, Windows API函數(shù)ABSTRACT This paper presents a method to develop image processing system with VB and knowledge about calling DLL in VB is briefly introduced,and a method to quickly acquire the value of bitmap and display bitmap with API function in VB,is last,this paper discusses how to program DLL for image processing with VC and using this DLL in VB.KEYWORDS image processing, hybrid language, DLL, Windows API function 在數(shù)字圖像處理中,需要進(jìn)行大量的數(shù)值計(jì)算,當(dāng)圖像較大時(shí)運(yùn)算量尤為可觀。以在圖像處理中常用的模板運(yùn)算為例,一個(gè)3*3的模板,完成一次操作每個(gè)像素要用9次乘法,8次加法。對于一幅N*N的圖像,就是9(N2)2次乘法,8(N2)2次加法操作,算法復(fù)雜度為0(N2),可見運(yùn)算量之大。所以在圖像處理中,一般選擇編譯后代碼執(zhí)行速度較快的VC來編程。不過相對于VB,VC的編程復(fù)雜性要大許多。特別是在界面編程時(shí),VB的所見即所得的特性能大大縮短編程的時(shí)間。如果采用在VB中調(diào)用VC編寫的動(dòng)態(tài)鏈接庫的方法,就能充分發(fā)揮兩者的優(yōu)點(diǎn),彌補(bǔ)雙方的不足。用VB來編寫界面等不涉及大量運(yùn)算的程序,用VC編寫的DLL來負(fù)責(zé)數(shù)值運(yùn)算的部分。這樣一來不僅能提高編程時(shí)的效率,縮短編程的時(shí)間,同時(shí)也能保證生成的程序的執(zhí)行速度,不會在圖像處理中耗時(shí)過多。1 在VB中調(diào)用動(dòng)態(tài)鏈接庫中的函數(shù)或例程 動(dòng)態(tài)鏈接庫是一種包含了一些函數(shù)和例程的可執(zhí)行文件,不過其本身不能單獨(dú)運(yùn)行,它只是為其他應(yīng)用程序提供服務(wù)。Windows API就是一種典型的DLL庫。為了在VB中使用DLL中導(dǎo)出的例程,必須首先告訴VB如何正確地向例程傳遞參數(shù),因此需要使用Declare語句對DLL中的例程進(jìn)行聲明。Declare語句的語法結(jié)構(gòu)有如下兩種:[Public Private]Declare Sub name Lib“l(fā)ibname”[Alias“aliasname”][([arglist])][Public Private] Declare Function name Lib“l(fā)ibname”[Alias“aliasname”][([arglist])][Astype]在類模塊或窗體模塊中的DLL過程只能被聲明為Private,并只能在模塊中使用。如果需要這個(gè)DLL過程能為工程中所有的模塊訪問,那么要?jiǎng)?chuàng)建一個(gè)標(biāo)準(zhǔn)模塊,并在標(biāo)準(zhǔn)模塊中使用Public來聲明該DLL。Name字句說明了聲明的過程名。Lib子句指明了包含所聲明過程的動(dòng)態(tài)鏈接庫或代碼資源,該動(dòng)態(tài)鏈接庫或代碼資源由libname指定。VB在傳遞參數(shù)時(shí)有兩種方式,按值的方式(ByVal)和按引用的方式(ByRef)傳遞。按值的方式傳遞時(shí),傳遞的實(shí)際上是變量的一個(gè)副本,接受該參數(shù)的過程所作的改變只針對該副本,不會影響變量本身。按引用的方式傳遞是VB6的缺省方式。在這種方式中,實(shí)際上傳遞的并不是變量的值,而是指向這個(gè)變量的32位地址。所調(diào)用的過程根據(jù)這個(gè)地址來獲取變量的實(shí)際值。這樣過程可以通過對地址中值的修改來達(dá)到修改參數(shù)原有值的目的。C/C++的數(shù)據(jù)類型與VB的數(shù)據(jù)類型并不相同。在VB中調(diào)用C或C++編寫的DLL,需要知道兩者數(shù)據(jù)類型之間的對應(yīng)關(guān)系。要說明的是并不是兩者之間所有的數(shù)據(jù)類型都能找到對應(yīng)關(guān)系。表1中列出了一些在VB參數(shù)聲明中常見的所用數(shù)據(jù)類型的對應(yīng)系統(tǒng)。表1 C中數(shù)據(jù)類型與聲明DLL過程所用參數(shù)格式的對應(yīng)關(guān)系聲明了DLL過程后,就可以在VB中使用過程名name訪問該過程。2 VB中獲取位圖的像素信息和顯示位圖 在VB中,使用圖片框控件可以很容易地完成打開圖像文件,顯示圖像以及儲存圖像等操作。但要對圖像進(jìn)行進(jìn)一步處理則必須獲取圖像的像素信息。在VB中快速地獲取Picture控件中顯示的圖像像素信息,或者將像素信息返回給位圖的方法是使用API函數(shù)。可以利用API函數(shù)GetObject獲取位圖格式信息。用GetBitmapBits獲取位圖的像素信息。用SetBitmapBits將像素信息返回給位圖并顯示出來。GetObject函數(shù)在VB中的聲明如下:[Public Private] Declare Function GetObjectLib gdi32 Alias GetObjectA (ByValhObject AsLong,Byval n Count As Logn,lpobject As Any)AsLonghObject是圖像對象(位圖、畫筆、刷子、字體、調(diào)色板等)的句柄,nCount是接受對應(yīng)圖像對象信息的結(jié)構(gòu)的字節(jié)數(shù),lpObject是指向接受對應(yīng)圖像對象信息的結(jié)構(gòu)的指針。如果是位圖,hObject是位圖的句柄,而接受圖像信息的結(jié)構(gòu)為BITMAP,其定義如下:[Public Private]Type BITMAP39。 14 bytes bmType As Long 39。指明了位圖的類型,這個(gè)值必須是0 bmWidth As Long 39。代表位圖以像素為單位的圖像寬度 bmHeight As Long 39。代表位圖以像素為單位的圖像高度 bmWidthBytes As Long39。指明了每個(gè)掃描行的字節(jié)數(shù)(即以字節(jié)為單位的圖像寬度),這個(gè)值必須可被2整除 bmPlanes As Integer 39。代表圖像的顏色面數(shù) bmBitsPixel As Integer 39。指明每個(gè)像素用幾位數(shù)據(jù)來表示(8,16,24,32) bmBits As Long 39。是指向圖像數(shù)據(jù)的指針。End TypeGetBitmapBits和SetBitmapBits分別用于從位圖中獲取圖像中的像素信息和把像素信息返回給位圖。兩者在VB中的聲明如下:[Public Private]Declare Function GetBitmapBitsLibgdi32AliasGetBitmapBits(ByVal hBitmap AsLong, ByVal dwCount As Long,lpBits As Any) AsLong[Public Private] Declare Function SetBitmapBits Libgdi32AliasSetBitmapBits(ByVal hBitmap As Long,ByValdwCount As Long,lpBits As Any)As Long其中hbitmap是位圖句柄,dwCount是圖像信息的大小,lpBits是保存圖像信息的地址。下面的程序說明了這三個(gè)API函數(shù)的用法。首先新建一個(gè)VB工程,在工程中添加一個(gè)Picture box控件Picture1和一個(gè)Command控件Command1,并在Picture box控件中加載一副圖片。然后分別聲明以下三個(gè)API函數(shù)和BITMAP類型。最后Command1的Click事件中添加下面的代碼。Dim Result As Long,totbytes As LongDim bmp As BITMAPDim ImgArray ()As ByteResult=GetObject(,Len(bmp),bmp)39。獲取位圖圖像格式信息totbytes=*39??偣惨嗌賯€(gè)Byte來存位圖ReDim ImgArray(totbytes)Result=GetBitmapBits(,totbytes,ImgArray(0)) 39。獲得位圖像素信息39。在這里加入對圖像像素?cái)?shù)據(jù)進(jìn)行處理的程序Call SetBitmapBits(,totbytes,ImgArray(0)) 39。顯示處理結(jié)果3 在VC中編寫DLL,在VB中調(diào)用為了在VC編寫的動(dòng)態(tài)鏈接庫中處理圖像像素,需要VB把獲取的位圖圖像像素信息傳送給DLL。在上文中,已經(jīng)介紹了獲取和返還像素信息的方法,這里實(shí)際上就是把存有像素信息的數(shù)組傳送給DLL。由于數(shù)值型的數(shù)組在VB中其數(shù)據(jù)是連續(xù)存放的,而在C/C++中數(shù)組可以等價(jià)于指向數(shù)組第一個(gè)元素的指針。那么可以用引用的方式把VB中數(shù)組的第一個(gè)元素的地址傳給VC編寫的DLL,在DLL中用一個(gè)指針來接收,這樣就達(dá)到了傳遞數(shù)組的目的。至于從DLL傳遞數(shù)組給VB,方法相同,只不過過程相反而已。注意在這個(gè)過程中VB和VC中的數(shù)據(jù)類型一定要對應(yīng)。同時(shí),因?yàn)樵贑/C++中并不檢查數(shù)組的界限,所以需要告訴DLL數(shù)組的大小。下面具體說明編寫和調(diào)用DLL的一般方法。先在VC中選擇新建一個(gè)MFC AppWizard(dll)Project,取名為Mydll,并接受下面的選項(xiàng)的默認(rèn)設(shè)置。接著在Globals項(xiàng)下添加一個(gè)新過程Myfunc,其定義如下:void stdcall Myfunc(BYTE*PicArray,BYTE*PicDest,long PicHeight,long Pic Width)其中PicArray是指向接受數(shù)組的指針,PicArray是指向輸出結(jié)果數(shù)組的指針,PicHeight和PicWidth分別是圖像的高度和寬度(以字節(jié)為單位)。然后在此過程中編寫具體的圖像處理程序。寫完后在Build Project之前,。因?yàn)樵赩B的命名規(guī)則中第一個(gè)字符不容許為“”,而VC編寫的過程,其默認(rèn)的導(dǎo)出函數(shù),會在函數(shù)名前加“”。所以只有強(qiáng)制VC按要求命名導(dǎo)出函數(shù)。,。同時(shí)在VB中對應(yīng)聲明Myfunc過程。Private Declare Sub Myfunc Lib“mydll”(PicArray As Byte, PicDest As Byte, ByVal picHeight As Long, ByVal PicWidth As Long)最后就可以直接在VB模塊中調(diào)用Myfunc,來對圖像進(jìn)行處理了。4 結(jié)論按照本文所述方法,可以比較方便地編寫圖像處理的程序,不需要在代碼編寫中花費(fèi)太多的精力,而且生成的程序執(zhí)行速度相比單純的VB編寫的程序執(zhí)行速度快了很多。經(jīng)過對比實(shí)驗(yàn)證明,使用這種方法生成的程序,執(zhí)行速度是純VB生成程序的5~6倍,基本與VC的速度相當(dāng)。參考文獻(xiàn)1 李勇平,王雪梅, :希望電子出版社,2001:18~302 [美]David J C++技術(shù)內(nèi)幕(第四版).北京:清華大學(xué)出版社,1999:55~633 :東南大學(xué)出版社,1999:69再談可視編程環(huán)境下BMP文件的顯示和保存摘要:本文研究提出了Windows位圖文件讀取顯示和存盤的一種實(shí)用技術(shù)方法。特定的圖像處理工作中,有時(shí)需要快捷的讀取顯示和存儲圖像數(shù)據(jù),無必要使用代碼龐大的DIB或DDB類來解決使用者的特定算法。位圖文件是可視編程環(huán)境中最基本的基礎(chǔ)圖像格式,因此,文章在分析了位圖的基本特點(diǎn)后,給出了在Win32 IDE環(huán)境下或者在Visual C++環(huán)境下實(shí)現(xiàn)這種要求的方法。結(jié)果表明,保存和顯示方法原理清晰,易于不同可視編程環(huán)境實(shí)現(xiàn)。關(guān)鍵詞:DIB。DDB。BMP。WIN32編程U