示例工程:http://files.cnblogs.com/laviewpbt/ImageShop.rar
聲明:1、如果你對VB語言有意見或者看不起他,依舊歡迎你評論,但請你不要用辱罵性的語言來評論。
2、本文不考慮項目的商業上的可行性及必要性。
3、本文不存在攻擊其他語言的目的。
這個問題我想了好久了,從畢業設計做圖像檢測開始接觸圖像,到工作中業余時間研究圖像,大概也有個四五年了,程序也從最開始的零星湊合到一個小小的完整版本,常常在走路或者睡覺前為了某個問題的解決方案而思索,也曾經一下子迷失而暫時喪失興趣。雖然到目前為止,整個工程還在改進和完善中,但是我已迫不及待的想和大家探討下各方面的可行性。
一、運行速度。
我想這是很多人對我這個想法提出首要反對的原因。很多人都曾經說過VB慢,VB很垃圾,當然即使是現在還是有不少人有這種認識和想法。我不會對此做評價,我僅從一下幾個方面來分析下速度問題。
1、VB本身的問題。 的確,在很多方面VB設計的有缺陷,雖然為了用戶開發的方便,其封裝了很多低層的操作,但使得我們在面對有些問題時難以下手,不過這些在圖像處理上是很少體現的。圖像中存在大量的算法,而這些算法常常涉及到像素值的計算,像素值是什麼,一般都是用Byte類型變量表示的,VB即使再怎麼差勁,對於這些整數的加減乘除運算的計算速度難道會比其他語言差很多嗎,我不這樣認為,VB的編譯器沒有那麼傻瓜。
2、指針問題。VB沒有顯式的給我們提供指針,而圖像計算中確常常和指針打交道。的確,這是C類語言的驕傲,VB為了安全,向用戶屏蔽了指針,從而造成了速度在一定程度上的損失,可是,熱愛VB的大俠們在很久前就尋放到了通往指針秘門的羊腸小道----模擬指針,因為是模擬,所以比C的效率稍微低了那麼一點點,但不是傳說中的50%甚至更少,因此,我認為這也不是個問題。
3、復雜性問題。圖像編輯軟件是很復雜的,VB能處理這麼復雜的流程嗎,這個東西在某一個層次上,用其他語言能實現的,我想VB也不會有什麼難題的。
4、優化問題。其實在很多情況下,VB慢是因為程序沒有做優化,比如沒有利用恰當的數據類型,沒有合適的利用中間數據,錯誤的運用運算符,可以查表的地方用了循環等等,根據我個人的經驗,同樣的算法,我優化後的和別人用其他工具優化後的執行結果不會有什麼出入。
從以上4個方面來說,采用VB和采用其他語言應該來說沒有什麼大的區別。可行。
二、資源占用
1、VB本身的問題。我們直接打開VB,然後什麼也不做,直接編譯,這個只有一個窗體而什麼都不做的程序大概占用了4MB左右的內存,有人對此心懷怨恨,如果在10年前,這可能是令人不爽的事情,而如今,在這個內存如此賤賣的年代,你還會在意嗎。
同時在VB程序的UI制作中,資源占用的大戶主要是PictureBox控件,不過我們的程序中不會有很多地方會用到他,並且這個占用的內存和我們打開的圖像及一些中間操作所需要的內存相比,所占的比例是比較小的。而後者是利用其他語言設計時同樣不可避免的部分。
2、圖層、選區、蒙版等。他們是資源占用大戶,舉個簡單的例子,如果打開一個1024*768大小的彩色圖像,並為其添加一個蒙版,則這三項所占用的內存約為(1024*768)*(3+1+1)=3.75MB的內存,如果有多個層,則相應的內存占用量就比較客觀了。而用戶在編輯圖像時,也可能打開了多個窗口,同時,在進行濾鏡處理時,往往需要創建一個當前圖像的備份,從而使得程序臨時占用的內存量增加很多。
另外,對於每一個活動窗口,我們還需要一個輸出顯示的緩沖區,這個緩沖區的大小不會超過屏幕的分辨率,因此,並且始終是一個32位的DIB,因此,在最壞的情況下,他占用了4MB左右的內存。
3、歷史記錄。這個要看程序怎麼設計,很多軟件具有無限重撤銷和恢復功能,我想這個他應該是把需要的數據備份到了硬盤,這樣做的一個結果是經常讀寫硬盤,個人認為是個不太合理的設計,要知道一副稍微大點的JPG文件加載到內存後,即使你采用了一些無損壓縮技術保存到硬盤,往往也有10MB左右,這種頻繁的讀寫在這個硬盤數據重要性大於一切的時代,似乎顯得有點蒼白。而類似於PS這種軟件都有一個最大的撤銷步驟數,這樣做的一個目的是為了速度考慮,一個方面是為了保護硬盤。因此,我認為在圖像處理中,在這樣一個時代背景下,歷史記錄功能還是得靠內存大哥來幫助的。如果最撤銷步數為20,並且每次都是對整幅圖像進行的處理,則1024*768大小的圖像因撤銷而占用的內存約為45MB,這是最壞的情況,實際中我們總會設計到一些小歷史內存占用的的操作,比如移動圖層,小選區內處理等。
如此說來,從速度和性能及用戶的利益角度來考慮,歷史記錄也是內存占用的大戶。這是圖像處理軟件的無奈。
三、用戶操作舒適度問題。
1、多線程問題。多線程一直是VB無法處理好的難題。在PS中,當我們移動一個層時,會明顯的感覺到界面有多個矩形小方塊在變換,這其實是為了考慮到用戶的舒適性而做的一個技巧,也是必須運用多線程才能比較方便實現的地方。因為鼠標的移動是個頻繁的事件,如果每移動一次,程序就響應更新,CPU是無法承擔如此重的負荷的,給用戶的感覺就是有點卡。在VB中要實現此效果,有很大的難度,這是一大遺憾。在我自己的工程中,我也只是通過優化輸出緩沖區中的混合速度而使得這個問題不是那麼明顯。
2、鍵鼠操作問題。鍵鼠操作可以說是反映一個軟件優良的關鍵標准,在技術實現上,這個也有很多學問,不過這東西應該是語言無關的,所以VB在這裡應該不會卡住。
3、界面問題。眾所周之,VB開發界面是最快捷和優秀的,所以,界面開發也不是關鍵問題所在。不過我自己因為對這個不怎麼在行,界面很普通。
四、技術實現上的一些問題
1、圖層。圖層可以說是圖像處理軟件的精華,關於圖層的實現,我有寫過一篇簡單的文章來描述,可以參見http://blog.csdn.net/laviewpbt/archive/2009/05/02/4143881.aspx。
2、蒙版。蒙版在兩幅或多副圖像的透明合成中具有很高的適用價值,蒙版,按照我的理解,實際上也是一副256色的灰度圖像,其大小和當前圖層一樣,如果某點為255,則表示當前層改點的透明度為不變,如果某點的值為127,則表示當前層改點的輸出透明度為實際透明度的一半。如果為0,則當前點完全不透明,直接顯示下部那一層的顏色值。而蒙版數據我們只會在計算輸出圖像時用到,並且由於其是一副256色的灰度圖像,因此濾鏡以及調整菜單中的效果都可以對齊使用,這和PS的情形是一致的,在技術實現上沒有難度。
3、選區。選區也是一個很重要的功能,在早期我的理解和實現中,選區是借用了Windows的region對象,利用這個對象很容易實現選區的並、差、異或等,且GetRegionDataA函數可以返回選區的每個小矩形的坐標,這樣就可以實現選區的像素處理。開源中比較著名的Paint.net軟件似乎也是利用的這個對象。但是利用region對象很難實現選區的抗鋸齒以及類似羽化這樣的高級功能。實際上,完美的選區是一副和畫布一樣大小的灰度圖,注意,這裡是和畫布一樣大小,灰度中的白色表示完全選中,黑色表示沒有選中,中間的其他值則表示了原始像素值和處理後的像素值的混合程度。比如如果原始點的紅色分量是160,對應的選區位置處的灰度值是200,則執行反色後改點的顏色值是(160*(255-200)+(255-160)*200)、255=109。為了達到抗鋸齒效果,需要借助於GDI+的相關函數,同時,實現羽化也較為簡單,對選區的灰度圖像進行高斯模糊就可以了。
4、調整菜單。調整菜單中的濾鏡之所以放在一起,我認為是因為他們都是對單個像素點進行的處理,而不涉及到領域像素。這裡面的算法有些可以自己推敲,復雜點的網絡上也有很多對其原理進行解釋的,而大部分開源軟件中都有設計這方面的代碼。把他們轉換成VB對我來說不是難事。
5、濾鏡菜單。濾鏡是圖像中最具有創意的東西,也是發揮個性最合適的地方。眾多的開源軟件中有著數以百計的濾鏡特效,要充實這個菜單可以說是簡單而又最能見效果的地方。Paint.net、Cximage、Gimp、Phoxo等等都是這方面寶貴的資源。
6、支持的格式。VB自身能支持JPG,BMP,GIF,ICO,WMF,EMF格式,但是由於在某些方面支持不全面,除了WMF,EMF外,還是采用GDI+讀取,GDI+可支持PNG、GIF、BMP、JPG、TIFF等格式。對於ICO格式,因其格式相對簡單,可以直接從文件讀取。另外,PCX、TGA的格式讀取也不是難事,而PSD格式因其復雜性,現在還只可以讀取其一層的圖像。
當然,還有其他的很多方面要考慮,但是我覺得,即使利用這款已經有了10年歷史的老工具,依舊還是能寫出很多具有很高價值的軟件的,VB不是生來就應該受到鄙視的。
附件中的工具還我是半年前的作品,有著很多很多的錯誤,新的作品還在完善中。