vb.net中彩色映像資料的快速擷取

來源:互聯網
上載者:User

         一直以來,影像處理都是VB的禁區,主要的原因可能是因為她沒有指標,而映像的資料量通常都很大。其實,只要有正確的方法,VB同樣可以寫出高效而又快速的影像處理程式的。

        我並不是學影像處理這方面的。可以說,我的專業和映像毫不佔邊,但因老闆項目的需要,自學了一些圖形映像學方面的知識。網路像方面大部分的代碼都是用VC寫的,對於我這個對C系列語言不感冒的人來說實在是太痛苦了,好在關鍵的演算法部分還能夠馬馬乎乎的看懂,這樣在學習中也改寫了不少代碼,這裡想共用一些常用的演算法供大家研究。

       要處理一個映像,首先當然要獲得該映像的像素值,常見很多人直接用兩個迴圈中調用GetPixel 來得到資料(最初我也是),這個過程是相當耗時,在處理完畢後又調用SetPixel 來更新映像,而SetPixel呢,要進行座標系轉化、剪裁地區判斷、將顏色匹配為裝置支援的最接近的,最後還要根據不同的顏色格式定址、為將顏色寫入其所在位進行位元運算,速度可想而知了。

       在VB6.0,為了快速得到一副映像的資料,通常需要調用API函數GetDIBits,而在調用該函數前要做大量的準備工作(API聲明、BITMAPINFO資訊設定等),也有點煩躁,但在.net中提供了BitmapData類,再結合Marshal類的Copy方法可以快速地複製映像資料到一維數組中。

        因為我的項目中只對彩色映像進行處理,而且不涉及到特效,所以沒有考慮到Alpha通道。

       以下是映像的讀取和儲存部分的代碼:

    '  ******************************************************************************************
    '
    '  函數名   :  ReadBitmap
    '  功能     :  讀取映像資料
    '  參數     :  Bmp          ------     Bitmap       待處理位元影像
    '               BmpData      ------     Byte         儲存映像的資料的數組(引用)
    '  作者     :  laviewpbt
    '  時間     :  2005-5-20  9:45
    '  修改者   :
    '  修改時間 :
    '
    '  ******************************************************************************************

    Public Shared Sub ReadBitmap(ByVal Bmp As Bitmap, ByRef BmpData() As Byte)
        Dim Data As BitmapData = Bmp.LockBits(New Rectangle(0, 0, Bmp.Width, Bmp.Height),                 ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb)     '  將Bitmap對象鎖定到系統記憶體中
        Dim Stride As Integer = Data.Stride       '   掃描寬度
        Dim Scan0 As IntPtr = Data.Scan0        '   位元影像中第一個像素資料的地址
        Dim Number As Integer = Bmp.Height * Stride - 1    ' 映像資料元素的個數,注意.net中數組下標是從0開始的
        ReDim BmpData(Number)  
        Marshal.Copy(Scan0, BmpData, 0, Number)   ‘將記憶體Scan0後面Number位元組的資料拷貝到BmpData中
        Bmp.UnlockBits(Data)   ' 從系統記憶體解鎖Bitmap
   End Sub

 

 
  '  ******************************************************************************************
    '
    '  函數名   :  WriteBitmap
    '  功能     :  將資料寫入映像
    '  參數     :  Bmp          ------     Bitmap       待處理位元影像
    '               BmpData      ------     Byte         儲存映像的資料的數組
    '  作者     :  laviewpbt
    '  時間     :  2005-5-20  9:49
    '  修改者   :
    '  修改時間 :
    '
    '  ******************************************************************************************

    Public Shared Sub WriteBitmap(ByVal Bmp As Bitmap, ByVal BmpData() As Byte)
        Dim Data As BitmapData = Bmp.LockBits(New Rectangle(0, 0, Bmp.Width, Bmp.Height), ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb)   '  '  將Bitmap對象鎖定到系統記憶體中
        Dim stride As Integer = Data.Stride       '    掃描寬度
        Dim Scan0 As IntPtr = Data.Scan0         '   位元影像中第一個像素資料的地址
        Dim Number As Integer = Bmp.Height * stride - 1      ' 映像資料元素的個數
        Marshal.Copy(BmpData, 0, Scan0, Number)     '將BmpData中的資料拷貝到Scan0後面的Number位元組中
        Bmp.UnlockBits(Data)     ' 從系統記憶體解鎖Bitmap
    End Sub

       Marshal.Copy方法的使用大大加速了資料的擷取,Marshal類還提供了ReadByte,WriteByte之類的方法,但利用這種方的效率也將非常低下。

        對於一副1024*768的24位真彩色映像,利用上述函數讀取資料所用的時間是0豪秒(呵呵,當然不是了,估計要用QueryPerformanceCounter函數來得到這個值,順便說下我的機器配置:256MB記憶體,Pentium 3.0G),也就是說,映像資料擷取可以達到毫秒級,這樣,我們就可以把大部分設計的精力投入到演算法的設計中去。

        上面所擷取的資料是一維數組,而24真彩色映像用一三維BmpData(width-1,height-1,2)數組來表示是相當便於處理的,但是如何快速的把資料寫入到一三維數組中,我還沒有發現好辦法,Marshal.Copy方法只支援一維數組的資料複製,如果用For迴圈來做,也是一個很漫長的過程。我曾經試著用CopyMemory ,雖然可以將記憶體中一段資料拷貝到一多維陣列中,但數組中的資料的順序不符合要求。

       不過說明一點,同樣的資料計算量,用一維數組要比用多維資料的速度要快些,這是很明顯的,所以經過一番思想鬥爭,我決定還是用一維數組來處理,雖然在計算中有些難以理解計算式的意義。

  

 

 
    

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.