(转)C#进行图像处理的几种方法(bitmap,bitmapData,IntPtr)
来源:互联网 发布:电视品牌推荐 知乎 编辑:程序博客网 时间:2024/05/16 08:58
转自 http://blog.sina.com.cn/s/blog_628821950100wh9w.html
使用C#进行图像处理的几种方法
本文讨论了C#图像处理中Bitmap类、BitmapData类和unsafe代码的使用以及字节对齐问题。
Bitmap类
命名空间:System.Drawing
封装 GDI+ 位图,此位图由图形图像及其属性的像素数据组成。Bitmap 是用于处理由像素数据定义的图像的对象。
public void GetPixel_Example(PaintEventArgs e) { // Create a Bitmap object from an image file. Bitmap myBitmap = new Bitmap("Grapes.jpg"); // Get the color of a pixel within myBitmap. Color pixelColor = myBitmap.GetPixel(50, 50); // Fill a rectangle with pixelColor. SolidBrush pixelBrush = new SolidBrush(pixelColor); e.Graphics.FillRectangle(pixelBrush, 0, 0, 100, 100); }
可见,Bitmap类使用一种优雅的方式来操作图像,但是带来的性能的降低却是不可忽略的。比如对一个800*600的彩色图像灰度化,其耗费的时间都要以秒为单位来计算。在实际项目中进行图像处理,这种速度是决对不可忍受的。
BitmapData类
命名空间:System.Drawing.Imaging
指定位图图像的属性。BitmapData 类由 Bitmap 类的 LockBits 和 UnlockBits 方法使用。不可继承。
- Width
获取或设置 Bitmap 对象的像素宽度。这也可以看作是一个扫描行中的像素数。 - Height
获取或设置 Bitmap 对象的像素高度。有时也称作扫描行数。 - PixelFormat
获取或设置返回此 BitmapData 对象的 Bitmap 对象中像素信息的格式。 - Scan0
获取或设置位图中第一个像素数据的地址。它也可以看成是位图中的第一个扫描行。 - Stride
获取或设置 Bitmap 对象的跨距宽度(也称为扫描宽度)。
private void LockUnlockBitsExample(PaintEventArgs e) { // Create a new bitmap. Bitmap bmp = new Bitmap("c:\\fakePhoto.jpg"); // Lock the bitmap's bits. Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height); System.Drawing.Imaging.BitmapData bmpData = bmp.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, bmp.PixelFormat); // Get the address of the first line. IntPtr ptr = bmpData.Scan0; // Declare an array to hold the bytes of the bitmap. int bytes = bmpData.Stride * bmp.Height; byte[] rgbValues = new byte[bytes]; // Copy the RGB values into the array. System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, bytes); // Set every red value to 255. for (int counter = 0; counter < rgbValues.Length; counter+=3) rgbValues[counter] = 255; // Copy the RGB values back to the bitmap System.Runtime.InteropServices.Marshal.Copy(rgbValues, 0, ptr, bytes); // Unlock the bits. bmp.UnlockBits(bmpData); // Draw the modified image. e.Graphics.DrawImage(bmp, 0, 150);}
上面的代码演示了如何用数组的方式来访问一幅图像,而不在使用低效的GetPixel()和SetPixel()。
unsafe代码
- 方法、类型和可被定义为不安全的代码块。
- 在某些情况下,通过移除数组界限检查,不安全代码可提高应用程序的性能。
- 当调用需要指针的本机函数时,需要使用不安全代码。
- 使用不安全代码将引起安全风险和稳定性风险。
- 在 C# 中,为了编译不安全代码,必须用 /unsafe 编译应用程序。
//创建图像 Bitmap image = new Bitmap( "c:\\images\\image.gif" ); //获取图像的BitmapData对像 BitmapData data = image.LockBits( new Rectangle( 0 , 0 , image.Width , image.Height ) , ImageLockMode.ReadWrite , PixelFormat.Format24bppRgb ); //循环处理 unsafe { byte* ptr = ( byte* )( data.Scan0 ); for( int i = 0 ; i < data.Height ; i ++ ) { for( int j = 0 ; j < data.Width ; j ++ ) { // write the logic implementation here ptr += 3; } ptr += data.Stride - data.Width * 3; } }
毫无疑问,采用这种方式是最快的,所以在实际工程中都是采用指针的方式来访问图像像素的。
字节对齐问题
|-------Stride-----------|
|-------Width---------| |
Scan0:
BGR BGR BGR BGR BGR BGR XX
BGR BGR BGR BGR BGR BGR XX
BGR BGR BGR BGR BGR BGR XX
.
.
.
- (转)C#进行图像处理的几种方法(bitmap,bitmapData,IntPtr)
- C#进行图像处理的几种方法(bitmap,bitmapData,IntPtr)
- [转]使用C#进行图像处理的几种方法
- [转]使用C#进行图像处理的几种方法
- 使用C#进行图像处理的几种方法
- 使用C#进行图像处理的几种方法
- C# Bitmap图像处理(含增强对比度的三种方法)
- c# byte[] 转换为 IntPtr几种方法
- Bitmap图片处理的效率----BitmapData
- Bitmap图片处理的效率----BitmapData
- Bitmap序列化(将BitmapData保存为原生Binary/ByteArray),AS3保存图像的方法
- c#图像处理入门的一个好方法-bitmap类和图像像素值获取方法
- C#使用内存法Marshal 方法和BitMapData处理任意24位彩色图像
- 使用BitmapData实现图像的高速处理
- 图像处理的几种方法
- asp.net中c# byte[] 转换为 IntPtr几种方法
- C#之BitmapData应用2 由数据转换为Bitmap图像
- C# 数组转Intptr
- JAVA NIO 简介
- apache shiro与spring整合、动态filterChainDefinitions、以及认证、授权
- 深度优先搜索
- EXCEL Range对象基本操作应用示例(1)
- JSTL控制表格换行
- (转)C#进行图像处理的几种方法(bitmap,bitmapData,IntPtr)
- itext(一)Chunk、Phrase、Paragraph的应用
- string与stringbuffer的性能对比
- CUDA by Example 4.2.2 一个有趣的例子 之 #include "gl_helper.h"
- 通过八数码问题学习A*算法
- Web工程师在线工具箱
- 如何让sharepoint2010网站根据权限隐藏ribbon
- fileupload文件上传(配合Uploadify使用)
- 第十三周上机任务项目3-汉诺塔