VB.NET中图像处理的有的技艺以及其和C#图像处理的差异。

  早期的时候自己利用的开发工具是VB6,VB6做图像处理的进程在自身的软件Imageshop中具备展现,仍旧算能够的。目前,我早就改用C#来探讨图像算法,C#中有指针,做图像处理起来功效真的要高不少。VB.NET当初也用过不到7个月的时日,在http://blog.csdn.net/laviewpbt/article/details/752003一文中我一度对VB.NET图像处理做了简便易行的下结论。后天就自己控制的状态,在对VB.NET的图像处理做一个大约的叙说。

     
首先,依然谈谈图像像素时多少得到方面呢,.net中的图像相关类基本上都是基于GDI+的,由此,图像数据的获得其实也是调用GDI+的有些函数。那几个函数就是LockBits,在vb.net中彩色图像数据的火速得到 一文中,大家是调用了马尔斯hal.Copy把LockBits锁定的内存数据拷贝到数据中,然后对数组中的值举行拍卖。那样做要紧的原因是VB.NET不佳直接访问内存(马尔斯hal.ReadByte之类的函数不适合用来大型的循环中)。那么,那就导致了2个不佳的政工,第一:在同一时间须要2倍于图像数据量的内存,第二:内存数据拷贝到数据,以及处理后再把数组的数目拷贝会内存中都是会稳中有降速度的。作为一种革新,大家相应丰富利用LockBits的功能。LockBits中的LockMode中有一种情势为ImageLockMode.UserInputBuffer,该方式下必要用户先申请内存,然后在把图像数据根据有关格式填充如这几个内存中。这样,就可以先定义个数组,然后把图像数据填充到那个数组中,就幸免了往来拷贝的耗时了,简单示例代码如下:

  Dim BmpData As New BitmapData
  Stride = ((Bmp.Width * 3 + 3) And &HFFFFFFFC)
  Dim PixleValue(Stride * Bmp.Height) As Byte
  Dim Hanlde As GCHandle = GCHandle.Alloc(PixleValue, GCHandleType.Pinned)
  BmpData.Scan0 = Hanlde.AddrOfPinnedObject()                                 '取得字节数组的的第一个元素在内存中的地址,VB.NET没有了VB6.0的VarPtr函数了
  BmpData.Stride = Stride                                                     'Stide这一个字段也必须实现填充,这个需要按照像素格式来计算大小,必须为4的倍数
  Bmp.LockBits(New Rectangle(0, 0, Bmp.Width, Bmp.Height), ImageLockMode.ReadWrite Or ImageLockMode.UserInputBuffer, PixelFormat.Format24bppRgb, BmpData)
  Hanlde.Free()    

  那种调用方式下,BitmapData对象的Scan0和Stride必须由用户自动总计,其中Scan0为保留解码后的多少内存的地方。在VB.NET中收获数组内存地址的代码如同比VB6扑朔迷离一些,那点我也不是特旨在行。

     
调用上述代码后,PixleValue就早已保存了图像的多少了。

     
之后就是对图像数据开展各类种种的拍卖了。比如我们那前一段日子共享的色调均化的代码为例:

        For Y = 0 To Height - 1
            Speed = Y * Stride                          ' 定位到每个扫描行的第一个像素,以避免溶于数据的影响
            For X = 0 To Width - 1
                HistGram(PixleValue(Speed)) += 1        ' Blue
                HistGram(PixleValue(Speed + 1)) += 1    ' Green
                HistGram(PixleValue(Speed + 2)) += 1    ' Red     
                Speed += 3                              ' 移向下一个像素
            Next
        Next

        Num = 0
        For Y = 0 To 255
            Num = Num + HistGram(Y)         ' 计算映射表
            Lut(Y) = CByte(Math.Truncate(CSng(Num) / (Width * Height * 3) * 255))
        Next
        For Y = 0 To Height - 1
            Speed = Y * Stride
            For X = 0 To Width - 1
                PixleValue(Speed) = Lut(PixleValue(Speed))
                PixleValue(Speed + 1) = Lut(PixleValue(Speed + 1))
                PixleValue(Speed + 2) = Lut(PixleValue(Speed + 2))
                Speed += 3
            Next
        Next

  执行进程相比:针对上述算法,大家只比较算法的实践部分的耗时。

      测试语言          
 测试图像(512*384)耗时      测试图像(1024*768)耗时  
 测试图像(4000*3000)耗时  

       VB.NET          
     7ms            
 25ms              178ms

        c# 指针        4ms      
                           16ms              100ms

        c# 数组                     5ms
                               
 24ms              139ms

   
 上表中可以肯定看出指针在进程上依然有明确的优势的,唯一值得注意的是,VB.NET的数组版要比C#的数组版的进度要慢,由于VB.NET中我不亮堂怎么样查看其对应的反汇编码,所以我还不知晓那是干什么。 

C#,   
 上述三种方案的代码下载:http://files.cnblogs.com/Imageshop/HistgramEqualize%28VB.NETandCsharp%29.rar

   
 看来VB.NET确实不是图像处理方案的首选工具啊。

 

 ***************************作者:
laviewpbt   时间: 2013.4.07    联系QQ:  33184777
 转发请保留本行新闻*************************

 

 

相关文章