- 浏览: 39865 次
-
文章分类
- 全部博客 (37)
- java (37)
- [文摘20081112]经典语录 (1)
- php+mysql预查询prepare 与普通查询的性能对比 (1)
- Android采用SharedPreferences保存用户登录信息 (1)
- 找bug记(2) (1)
- 细节优化提升资源利用率 (1)
- java(j2se)学习笔记----类注释文档编写方法? (1)
- 如何查看Class文件编译的JDK版本 (1)
- 验证码显示不了,报Could not initialize class sun.awt.X11GraphicsEnvironment (1)
- Android使用KSOAP2调用WebService及正确导入jar包的问题 (1)
- The content of the adapter has changed but ListView did not receive a notification. (1)
- 很想写些CMMI的东西 (1)
- JPA & Hibernate 注解 (1)
- Java反编译工具――Jode (1)
- Eclipse3.0.0插件安装解决方法 (1)
- SVG简介及相关工具 (1)
- 开始在这个BLOG里放一部分MapXtreme2004相关代码 (1)
- 支持.NET环境的GIS开发工具MapXtreme2004 (1)
- 将DAT格式视频文件转换成ASF和WMV格式视频文件 (1)
- 《漫谈设计模式》一书终于出版了 (1)
- 一位程序员的一个LBS应用的想法 (1)
- 一刷网络投票的小程序 (1)
- 面试字符串处理之单词翻转 (1)
- rails 上载xls文件 (1)
- 如何获得Java项目文件所在的相对路径 (1)
- 学习FlexViewer(一)——事件和框架 (1)
- Android开发之消息处理机制(二)——消息循环 (1)
- JAVA操作——获取文件扩展名,去掉文件扩展名 (1)
- freemarker 读取session 值 (1)
- xfire 使用用户名/密码进行身份认证 (1)
- java中的图片处理 (1)
- HTC Touch HD2/LEO/T8585刷机教程 进三色屏 (1)
- js性能问题 (1)
- js 事件收集 (1)
最新评论
-
Glorin:
非常感谢你,让我的问题能够得以解决。
验证码显示不了,报Could not initialize class sun.awt.X11GraphicsEnvironment -
thzthbthy:
/*
* Java文件操作 获取文件扩展名
*
...
JAVA操作——获取文件扩展名,去掉文件扩展名 -
jyjava:
你debug调试,应该很快会定位到的
找bug记(2) -
xuehua1987:
上面的方法返回值是void ,怎么可以返回你取到的连接???? ...
找bug记(2)
<p><a target="_blank">本文转自:<font><a href="http://conner-wang.spaces.live.com/blog/cns!568d1f7f9d97c059!488.entry">http://conner-wang.spaces.live.com/blog/cns!568d1f7f9d97c059!488.entry</a></font>本文讨论了c#图像处理中bitmap类、bitmapdata类和unsafe代码的使用以及字节对齐问题。 <font color="#ff8000"><strong>bitmap类</strong></font> <font color="#0080ff">命名空间:system.drawing</font> <font color="#0080ff">封装 gdi+ 位图,此位图由图形图像及其属性的像素数据组成。bitmap 是用于处理由像素数据定义的图像的对象。</font> 利用c#类进行图像处理,最方便的是使用bitmap类,使用该类的getpixel()与setpixel()来访问图像的每个像素点。下面是msdn中的示例代码:<blockquote><font color="#8000ff">public void getpixel_example(painteventargs e) <br>{ <br> // create a bitmap object from an image file. <br> bitmap mybitmap = new bitmap("grapes.jpg"); <br> // get the color of a pixel within mybitmap. <br> color pixelcolor = mybitmap.getpixel(50, 50); <br> // fill a rectangle with pixelcolor. <br> solidbrush pixelbrush = new solidbrush(pixelcolor); <br> e.graphics.fillrectangle(pixelbrush, 0, 0, 100, 100); <br>}</font> </blockquote> 可见,bitmap类使用一种优雅的方式来操作图像,但是带来的性能的降低却是不可忽略的。比如对一个800*600的彩色图像灰度化,其耗费的时间都要以秒为单位来计算。在实际项目中进行图像处理,这种速度是决对不可忍受的。 <font color="#ff8000"><strong>bitmapdata类</strong></font> <font color="#0080ff">命名空间:system.drawing.imaging</font> <font color="#0080ff">指定位图图像的属性。bitmapdata 类由 bitmap 类的 lockbits 和 unlockbits 方法使用。不可继承。</font> 好在我们还有bitmapdata类,通过bitmapdata bitmapdata lockbits ( )可将 bitmap 锁定到系统内存中。该类的公共属性有:<ul><li>width 获取或设置 bitmap 对象的像素宽度。这也可以看作是一个扫描行中的像素数。</li> <li>height 获取或设置 bitmap 对象的像素高度。有时也称作扫描行数。</li> <li>pixelformat 获取或设置返回此 bitmapdata 对象的 bitmap 对象中像素信息的格式。</li> <li>scan0 获取或设置位图中第一个像素数据的地址。它也可以看成是位图中的第一个扫描行。</li> <li>stride 获取或设置 bitmap 对象的跨距宽度(也称为扫描宽度)。 </li></ul> 下面的msdn中的示例代码演示了如何使用 pixelformat、height、width 和 scan0 属性;lockbits 和 unlockbits 方法;以及 imagelockmode 枚举。<blockquote><font color="#8000ff">private void lockunlockbitsexample(painteventargs e) <br>{ </font><font color="#8000ff"> // create a new bitmap. <br> bitmap bmp = new bitmap("c:\\fakephoto.jpg"); </font><font color="#8000ff"> // lock the bitmap's bits. <br> rectangle rect = new rectangle(0, 0, bmp.width, bmp.height); <br> system.drawing.imaging.bitmapdata bmpdata = <br> bmp.lockbits(rect, system.drawing.imaging.imagelockmode.readwrite, <br> bmp.pixelformat); <br> // get the address of the first line. <br> intptr ptr = bmpdata.scan0; </font><font color="#8000ff"> // declare an array to hold the bytes of the bitmap. <br> // this code is specific to a bitmap with 24 bits per pixels. <br> int bytes = bmp.width * bmp.height * 3; <br> byte[] rgbvalues = new byte[bytes]; </font><font color="#8000ff"> // copy the rgb values into the array. <br> system.runtime.interopservices.marshal.copy(ptr, rgbvalues, 0, bytes); </font><font color="#8000ff"> // set every red value to 255. <br> for (int counter = 0; counter < rgbvalues.length; counter+=3) <br> rgbvalues[counter] = 255; <br> // copy the rgb values back to the bitmap <br> system.runtime.interopservices.marshal.copy(rgbvalues, 0, ptr, bytes); </font><font color="#8000ff"> // unlock the bits. <br> bmp.unlockbits(bmpdata); </font><font color="#8000ff"> // draw the modified image. <br> e.graphics.drawimage(bmp, 0, 150); </font><font color="#8000ff">} </font></blockquote> 上面的代码演示了如何用数组的方式来访问一幅图像,而不在使用低效的getpixel()和setpixel()。 <font color="#ff8000"><strong>unsafe代码</strong></font> 而在实际中上面的做法仍然不能满足我们的要求,图像处理是一种运算量比较大的操作,不同于我们写的一般的应用程序。我们需要的是一种性能可以同c++程序相媲美的图像处理程序。c++是怎么提高效率的呢,答曰:指针。幸运的是.net也允许我们使用指针,只能在非安全代码块中使用指针。何谓非安全代码? 为了保持类型安全,默认情况下,c# 不支持指针运算。不过,通过使用 unsafe 关键字,可以定义可使用指针的不安全上下文。在公共语言运行库 (clr) 中,不安全代码是指无法验证的代码。c# 中的不安全代码不一定是危险的,只是其安全性无法由 clr 进行验证的代码。因此,clr 只对在完全受信任的程序集中的不安全代码执行操作。如果使用不安全代码,由您负责确保您的代码不会引起安全风险或指针错误。不安全代码具有下列属性:<ul><li>方法、类型和可被定义为不安全的代码块。</li> <li>在某些情况下,通过移除数组界限检查,不安全代码可提高应用程序的性能。</li> <li>当调用需要指针的本机函数时,需要使用不安全代码。</li> <li>使用不安全代码将引起安全风险和稳定性风险。</li> <li>在 c# 中,为了编译不安全代码,必须用 /unsafe 编译应用程序。 </li></ul> 正如《c#语言规范》中所说无论从开发人员还是从用户角度来看,不安全代码事实上都是一种“安全”功能。不安全代码必须用修饰符 unsafe 明确地标记,这样开发人员就不会误用不安全功能,而执行引擎将确保不会在不受信任的环境中执行不安全代码。 以下代码演示如何借助bitmapdata类采用指针的方式来遍历一幅图像,这里的unsafe代码块中的代码就是非安全代码。<blockquote><font color="#8000ff">//创建图像 <br>bitmap image = new bitmap( "c:\\images\\image.gif" ); <br>//获取图像的bitmapdata对像 <br>bitmapdata data = image.lockbits( new rectangle( 0 , 0 , image.width , image.height ) , imagelockmode.readwrite , pixelformat.format24bpprgb ); <br>//循环处理 <br>unsafe <br>{ <br> byte* ptr = ( byte* )( data.scan0 ); <br> for( int i = 0 ; i < data.height ; i ++ ) <br> { <br> for( int j = 0 ; j < data.width ; j ++ ) <br> { <br> // write the logic implementation here <br> ptr += 3; <br> } <br> ptr += data.stride - data.width * 3; <br> } <br>} </font></blockquote> 毫无疑问,采用这种方式是最快的,所以在实际工程中都是采用指针的方式来访问图像像素的。 <font color="#ff8000"><strong>字节对齐问题</strong></font> <br> 上例中ptr += data.stride - data.width * 3,表示跨过无用的区域,其原因是图像数据在内存中存储时是按4字节对齐的,具体解释如下: 假设有一张图片宽度为6,假设是format24bpprgb格式的(每像素3字节,在以下的讨论中,除非特别说明,否则bitmap都被认为是24位rgb)。显然,每一行需要6*3=18个字节存储。对于bitmap就是如此。但对于bitmapdata,虽然data.width还是等于image.width,但大概是出于显示性能的考虑,每行的实际的字节数将变成大于等于它的那个离它最近的4的整倍数,此时的实际字节数就是stride。就此例而言,18不是4的整倍数,而比18大的离18最近的4的倍数是20,所以这个data.stride = 20。显然,当宽度本身就是4的倍数时,data.stride = image.width * 3。 画个图可能更好理解。r、g、b 分别代表3个原色分量字节,bgr就表示一个像素。为了看起来方便我在们每个像素之间插了个空格,实际上是没有的。x表示补足4的倍数而自动插入的字节。为了符合人类的阅读习惯我分行了,其实在计算机内存中应该看成连续的一大段。 |-------stride-----------| <br>|-------width---------| | <br>scan0: <br>bgr bgr bgr bgr bgr bgr xx <br>bgr bgr bgr bgr bgr bgr xx <br>bgr bgr bgr bgr bgr bgr xx <br>. <br>. <br>. 首先用data.scan0找到第0个像素的第0个分量的地址,这个地址指向的是个byte类型,所以当时定义为byte* ptr。行扫描时,在当前指针位置(不妨看成当前像素的第0个颜色分量)连续取出三个值(3个原色分量。注意,0 1 2代表的次序是b g r。在取指针指向的值时,貌似p[n]和p += n再取p[0]是等价的),然后下移3个位置(ptr += 3,看成指到下一个像素的第0个颜色分量)。做过bitmap.width次操作后,就到达了bitmap.width * 3的位置,应该要跳过图中标记为x的字节了(共有stride - width * 3个字节),代码中就是 ptr += datain.stride - datain.width * 3。 通过阅读本文,相信你已经对使用c#进行图像处理可能用到的几种方法有了一个了解。至于采用哪种方式,取决于你的性能要求。其中第一种方式最优雅;第三种方式最快,但不是安全代码;第二种方式取了个折中,保证是安全代码的同时又提高了效率。熟悉c/c++编程的人可能会比较偏向于第三种方式,我个人也比较喜欢第三种方式。 <strong><font color="#ff8000">参考:</font></strong> 1. msdn2005 2. c#语言规范 3. </a><a href="http://www.codersource.net/csharp_image_processing.aspx" target="_blank">basic image processing support in c#</a> 4. <a href="http://blog.csdn.net/ki1381/archive/2007/01/10/1478611.aspx">使用c#的bitmapdata</a> 作者:<a href="http://conner-wang.spaces.live.com/">http://conner-wang.spaces.live.com/</a>转载请注明出处!</p>
发表评论
-
js 事件收集
2012-02-08 13:18 583一般事件 事件 浏 ... -
js性能问题
2012-02-08 13:13 789随着web应用的复杂度日渐提高,JavaScript代 ... -
HTC Touch HD2/LEO/T8585刷机教程 进三色屏
2012-02-07 15:53 1094[size=14px; line-height: 21 ... -
java中的图片处理
2012-02-04 12:44 797附件中的文件包括: 1.图片的压缩 2.处理圆角图片 ... -
xfire 使用用户名/密码进行身份认证
2012-02-03 16:59 1208对SOAP报文进行身 ... -
freemarker 读取session 值
2012-02-03 08:25 2539<span style="font-f ... -
JAVA操作——获取文件扩展名,去掉文件扩展名
2012-01-31 14:08 2320<p> 昨天收邮件,得知要参加一个产品部的 ... -
Android开发之消息处理机制(二)——消息循环
2012-01-11 14:53 843<h1>Android开发 ... -
学习FlexViewer(一)——事件和框架
2012-01-11 11:44 1240????? 上午做了关于FlexViewer的讲座,项 ... -
如何获得Java项目文件所在的相对路径
2011-12-28 15:08 2284[size=18px;]今天在开发中做一个java项 ... -
rails 上载xls文件
2011-12-21 12:14 1116?<span style="font- ... -
面试字符串处理之单词翻转
2011-12-21 11:34 910<p align="left&quo ... -
一刷网络投票的小程序
2011-12-20 11:44 1319最近看到网上一投 ... -
一位程序员的一个LBS应用的想法
2011-12-20 10:14 759最近状态不佳, ... -
《漫谈设计模式》一书终于出版了
2011-12-19 13:09 948<p class="MsoNor ... -
将DAT格式视频文件转换成ASF和WMV格式视频文件
2011-12-17 15:29 891以*.ASF和*.WMV为后缀名的视频文件,是微软针对 ... -
支持.NET环境的GIS开发工具MapXtreme2004
2011-12-16 16:12 704<font color="#ff000 ... -
开始在这个BLOG里放一部分MapXtreme2004相关代码
2011-12-15 14:38 564MapXtreme2004是嵌入到.NET环境中的地理 ... -
SVG简介及相关工具
2011-12-14 15:47 754<span style="" ... -
Eclipse3.0.0插件安装解决方法
2011-12-14 15:27 793<p class="MsoNorma ...
相关推荐
在本文中,我们将深入探讨C#中的数字图像处理技术,主要关注平滑、修正、锐化和增强等关键概念。...而文件"7ba49340eefa45bf84263efb0c55e807"可能包含的就是一个具体的C#图像处理程序实例,可作为学习和研究的起点。
在C#中,数字图像处理是一项关键技能,它涉及到对图像数据的分析、变换和操作,以实现各种视觉效果或进行科学分析。本实例集主要探讨了几个重要的图像处理算法,包括腐蚀、膨胀、开运算、闭运算和击中不击中算法,...
C#作为一种强大的编程语言,具有丰富的库和工具支持进行图像处理。本资源"‘C#数字图像处理算法典型实例源代码’"提供了一系列的C#实现的图像处理算法,对于开发者来说是极好的学习资料,可以提升实际开发技能。 ...
C#作为一种现代、面向对象的编程语言,由于其易读性强、库支持丰富,成为了开发图像处理应用的常用工具。本资源是针对《C#数字图像处理算法典型实例》一书的随书光盘代码,旨在帮助读者深入理解和实践图像处理技术。...
在图像处理领域,C#提供了System.Drawing命名空间,其中包含了大量用于处理图像的类和方法,如Bitmap、Graphics和ColorMatrix等。这些工具使得开发者能够轻松地进行像素级别的操作,实现诸如图像裁剪、旋转、色彩...
《C#数字图像处理算法典型实例》是一本深入探讨如何使用C#编程语言进行数字图像处理的书籍。作者赵春江在2009年3月出版此书,旨在为读者提供一系列实用的图像处理算法及其C#实现,帮助开发者理解和掌握图像处理技术...
在这个“C#数字图像处理<七>”的主题中,我们将深入探讨图像平滑与去噪的几种常见方法。 图像平滑是图像处理中的一个关键步骤,其主要目的是减少图像中的噪声和干扰,同时尽可能保持图像的主要特征。噪声通常是由...
Emgu CV允许C#开发者使用OpenCV的强大功能,包括图像读取、显示、保存,以及复杂图像处理任务,如特征提取、物体识别、面部检测等。 在这个“图像处理软件源码”中,我们可以期待看到以下几个关键知识点: 1. 图像...
在《Visual C#图像处理程序设计实例》这个主题中,我们深入探讨了使用C#语言进行图像处理的各种技术和方法。C#,作为一种强大的面向对象的编程语言,为开发者提供了丰富的库和工具,使得图像处理变得相对简单且高效...
在C#中进行数字图像处理,主要涉及以下几个关键知识点: 1. **基础概念**:首先,我们需要理解图像的基本构成,包括像素、色彩模型(如RGB、CMYK等)、图像格式(如JPEG、PNG、BMP等)。这些基础知识是进行图像处理...
C# 常见错误处理的几种方法 C# 中的错误处理是编程中不可或缺的一部分,它能够帮助开发者检测和解决程序中的错误。在 C# 中,错误处理是通过 try-catch 块来实现的,try 块中包含可能出现错误的代码,而 catch 块中...
本文将深入探讨几种常见的C#实现的图像平滑去噪技术,包括中值滤波、灰度形态学滤波、小波变换去噪、高斯低通滤波以及统计滤波。 首先,我们来看**中值滤波**。中值滤波是一种非线性的降噪方法,特别适合去除椒盐...
总之,"c#图像处理程序源码"是一个宝贵的资源,适合初学者和有经验的开发者学习和参考,可以帮助他们在C#环境下构建自己的图像处理工具或应用,进一步提升其编程技能。无论是为了个人兴趣还是专业发展,这个项目都是...
在C#编程环境中,图像处理是一项重要的功能,它允许开发者对图像进行各种操作,包括创建特效、修改像素、转换格式等。在这个特定的场景中,我们关注的是如何使用C#来实现图片的倒影效果以及水波纹效果。这两种效果在...
"C#数字图像处理<九>"着重探讨了如何使用C#进行图像分割,这是计算机视觉中的核心任务,目的是将图像划分为具有不同属性的区域,以便进一步分析和理解。以下将详细阐述图像分割的基本概念、常用方法以及与VS2010和C#...
本项目主要关注了几个关键的图像处理技术:锐化、半色调处理以及直方图均衡化。这些技术在图像增强、视觉效果改进以及图像分析等领域有着广泛应用。 1. **锐化**: 锐化是提高图像边缘对比度的过程,使得图像细节...
本文将深入探讨C#中的图形图像处理技术,包括如何打开和保存图像,实现图像效果如黑白、浮雕和灰度,以及如何进行基本的绘图操作如添加水印、画直线和曲线。 首先,C#提供了System.Drawing命名空间,它是进行图像...
在图像处理领域,C#是一种常用的编程语言,用于创建各种图像操作和效果。在这个特定的项目中,"C#实现图像变形(扭曲、水波纹、B样条)"涉及了几个关键知识点,包括基本的图像操作、图像变形算法、数学变换以及图形...
在C#中,有几种常见的模糊方法: 1. **高斯滤波**:高斯滤波是一种线性平滑滤波,通过应用高斯函数权重对图像像素进行加权平均,有效地降低了高频噪声。C#中可以使用二维卷积实现,通过定义一个高斯核矩阵并遍历每...
C#结合了.NET Framework的强大功能,使得在Windows环境中进行图像处理变得便捷。 图像边缘检测通常涉及到几种经典的算法,如Sobel、Prewitt、Canny、Laplacian等。这些算法都是通过计算图像的梯度或二阶导数来确定...