早期的时候我使用的开发工具是VB6,VB6做图像处理的速度在我的软件Imageshop中有所体现,还是算可以的。目前,我已经改用C#来研究图像算法,C#中有指针,做图像处理起来效率确实要高不少。VB.NET当初也用过不到半年的时间,在http://blog.csdn.net/laviewpbt/article/details/752003一文中我曾经对VB.NET图像处理做了简单的总结。今天就我掌握的情况,在对VB.NET的图像处理做一个简单的描述。

首先,还是谈谈图像像素时数据获取方面吧,.net中的图像相关类基本上都是基于GDI+的,因此,图像数据的获取其实也是调用GDI+的一些函数。这个函数就是LockBits,在vb.net中彩色图像数据的快速获取 一文中,我们是调用了Marshal.Copy把LockBits锁定的内存数据拷贝到数据中,然后对数组中的值进行处理。这样做主要的原因是VB.NET不好直接访问内存(Marshal.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中我不知道怎么样查看其对应的反汇编码,所以我还不清楚这是为什么。

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

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

***************************作者: laviewpbt   时间: 2013.4.07    联系QQ:  33184777  转载请保留本行信息*************************

VB.NET中图像处理的一些技巧以及其和C#图像处理的差距。的更多相关文章

  1. [转载]C#中MessageBox.Show用法以及VB.NET中MsgBox用法

    一.C#中MessageBox.Show用法 MessageBox.Show (String) 显示具有指定文本的消息框. 由 .NET Compact Framework 支持. MessageBo ...

  2. Handlebars.js循环中索引(@index)使用技巧(访问父级索引)

    使用Handlebars.js过程中,难免会使用循环,比如构造数据表格.而使用循环,又经常会用到索引,也就是获取当前循环到第几次了,一般会以这个为序号显示在页面上. Handlebars.js中获取循 ...

  3. VB.NET中的除法运算符 与 C#中的除法运算符

    VB.NET中的除法运算符有两个:/(浮点除法).\(整数除法) C#中的除法运算符只有一个:/(除法) VB.NET中的除法运算符与C#中的除法运算符存在很大的差异,使用时注意区分. 关于VB.NE ...

  4. VB6中的引用传递 与 VB.NET中的引用传递的区别

    首先注意一点,在VB6中缺省参数传递的方式是:引用传递,而在VB.NET中缺省参数传递的方式是:值传递. 然后我们看下面VB6中的引用传递与VB.NET中的引用传递的对比. VB6中的引用传递 Pri ...

  5. VB.NET中使用Linq TO SQL添加数据后获得自增长列ID

    VB.NET中使用Linq TO SQL添加数据后获得自增长列ID: Dim tempOrdre As New Order With { .CustomerID = cmbCustomerName.S ...

  6. Visual Studio 2015中的常用调试技巧分享

    .NET 技术交流群:337901356 欢迎您的加入! 为什么要学习调试? 调试(Debug)是作为一个程序员必须要学会的东西,学会调试可以极大的提高开发效率,排错时间,很多人不喜欢调试,但我认为这 ...

  7. VB.NET中DataGridView控件

    VB.NET中对于表格数据的显示经常使用到DataGridView控件,其以丰富多样的数据表呈现形式被程序猿喜爱. 本人在做一个小系统中运用DataGridView控件的部分属性,这些功能的使用在使用 ...

  8. vb.net中存储过程的使用

    在机房收费系统过程中,试着使用了存储过程,离之前数据库的学习已经有些日子了.之前对于存储过程的了解也是听过而已,非常不清楚.因此,写这篇博客! 专业概念:存储过程是一个SQL语句和控制结构的集合,创建 ...

  9. ACM 做题过程中的一些小技巧。

    ACM做题过程中的一些小技巧. 1.一般用C语言节约空间,要用C++库函数或STL时才用C++; cout.cin和printf.scanf最好不要混用. 2.有时候int型不够用,可以用long l ...

随机推荐

  1. sql常用语句(1)

    --排序 select Row_Number() over(order by a.UserName) as Num --区分性别 then '男' else '女' end SexName Sqlse ...

  2. Asp.net 面向接口可扩展框架之核心容器(含测试代码下载)

    新框架的容器部分终于调通了!容器实在太重要了,所以有用了一个名词叫“核心容器”. 容器为什么那么重要呢?这个有必要好好说道说道. 1.首先我们从框架名称面向接口编程说起,什么是面向接口编程?(这个度娘 ...

  3. ABP之动态WebAPI(一)

    ABP的动态WebApi实现了直接对服务层的调用(其实病没有跨过ApiController,只是将ApiController公共化,对于这一点的处理类似于MVC,对服务端的 调用没有跨过HttpHan ...

  4. 帆布指纹识别(canvas fingerprinting)

    广告联盟或许网站运营者都希望能够精准定位并标识每一个个体,通过对用户行为的分析(浏览了哪些页面?搜索了哪些关键字?对什么感兴趣?点了哪些按钮?用了哪些功能?看了哪些商品?把哪些放入了购物车等等),为用 ...

  5. Lind.DDD.Domain.IOwnerBehavor对实体的意义

    回到目录 对于Lind.DDD架构,我之前写了不少文章,对于它的Domain模式也介绍了不少,像之前的IEntity,ILogicDeleteBehavor,IModifyBehavor,IStatu ...

  6. Python开发【第一篇】:初识Python

    初识python 一.python简介 python的创始人为吉多·范罗苏姆(Guido van Rossum).1989年的圣诞节期间,吉多·范罗苏姆为了在阿姆斯特丹打发时间,决心开发一个新的脚本解 ...

  7. Aircrack-ng: (1) 概述

    目录 一.概述 二.工具与命令介绍 Linux命令 (1) ifconfig (2) macchanger (3) iwconfig (4) iwlist Aircrack-ng 工具 (1) air ...

  8. 委托的N种写法,你喜欢哪种?

    一.委托调用方式 1. 最原始版本: delegate string PlusStringHandle(string x, string y); class Program { static void ...

  9. ReactiveCocoa代码实践之-RAC网络请求重构

    前言 RAC相比以往的开发模式主要有以下优点:提供了统一的消息传递机制:提供了多种奇妙且高效的信号操作方法:配合MVVM设计模式和RAC宏绑定减少多端依赖. RAC的理论知识非常深厚,包含有FRP,高 ...

  10. iOS 疑难杂症 — — Swift debugger 无法在控制台 po 变量值的问题

    前言 这个问题出现有好几个月了,一直没弄,以为是 Xcode 的问题后面版本升级应该就能好所以就不管了,今天心情好顺便查了一下. 声明  欢迎转载,但请保留文章原始出处:)  博客园:http://w ...