注册本站  论坛  繁體中文

慧民电脑芯片级维修-电脑技巧
手机 | MP3 | MP4 | 显卡 | 主板 | 显示器 | 光存储 | 笔记本 | 网络设备 | 移动存储 | 数码相机
键鼠 | CPU | 音箱 | GPS | 电视 | 服务器 | 投影机 | 机箱电源 | 品牌电脑 | 办公打印 |
| 网站首页 | Cisco | Windows | Linux | Java | Dotnet | Oracle | 网页设计 | 平面设计 | 安全 | 软件应用 | 电脑维修 | 办公维修 |
您现在的位置: 电脑技巧 >> Dotnet >> C# >> Dotnet正文

编程中使用C#的BitmapData实例

文章来源:aspcool 作者:佚名 更新时间:2008-10-6 13:55:25 【 】 【加入收藏

  最近要转开发平台,正研究C#.C#好是好,不过处理图片时一个像素一个像素的操作像素不是一般的慢。其实Delphi也一样,但好在Delphi的Bitmap类提供了ScanLines,可以一行一行的读图,效率比较高。C#应该也有类似的东东。经过一番搜索,终于发现了BitmapData类。
 
  先看个例子,这是对一张位图的每个像素按FF取补,然后输出到一个新图(代码有点啰嗦,不过应该可以说明问题了)。
int h = m_Bmp.Height;
int w = m_Bmp.Width;

Bitmap bmpOut = new Bitmap(w, h, PixelFormat.Format24bppRgb);

BitmapData dataIn = m_Bmp.LockBits(new Rectangle(0,0,w,h),ImageLockMode.ReadOnly,PixelFormat.Format24bppRgb);
BitmapData dataOut = bmpOut.LockBits(new Rectangle(0, 0, w, h), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);

unsafe
{
byte* pIn = (byte*)(dataIn.Scan0.ToPointer());
byte * pOut = (byte*)(dataOut.Scan0.ToPointer());

for (int y = 0; y < dataIn.Height; y++)
{
for (int x = 0; x < dataIn.Width; x++)
{

pOut[0] = (byte)(255 - pIn[0]);
pOut[1] = (byte)(255 - pIn[1]);
pOut[2] = (byte)(255 - pIn[2]);

pIn += 3;
pOut += 3;
}

pIn += dataIn.Stride - dataIn.Width * 3;
pOut += dataOut.Stride - dataOut.Width * 3;
}
}

bmpOut.UnlockBits(dataOut);
m_Bmp.UnlockBits(dataIn);

  貌似比Delphi复杂得多,难道我真的天生对指针过敏?还是Delphi的比较好理解,就是扫描每一行,然后对当前像素点的三个分量做处理,非常方便。而且C#代码中的Stride是个什么东东?

查找了不少资料,现在我是这么理解的:

  假设有一张图片宽度为6,因为是Format24bppRgb格式(每像素3字节。在以下的讨论中,除非特别说明,否则Bitmap都被认为是24位RGB)的,显然,每一行需要6*3=18个字节存储。对于Bitmap就是如此。但对于BitmapData,虽然BitmapData.Width还是等于Bitmap.Width,但大概是出于显示性能的考虑,每行的实际的字节数将变成大于等于它的那个离它最近的4的整倍数,此时的实际字节数就是Stride。就此例而言,18不是4的整倍数,而比18大的离18最近的4的倍数是20,所以这个BitmapData.Stride = 20。显然,当宽度本身就是4的倍数时,BitmapData.Stride = Bitmap.Width * 3。

  画个图可能更好理解。R、G、B 分别代表3个原色分量字节,BGR就表示一个像素。为了看起来方便我在每个像素之间插了个空格,实际上是没有的。X表示补足4的倍数而自动插入的字节。为了符合人类的阅读习惯我分行了,其实在计算机内存中应该看成连续的一大段。

Scan0
 
 ---------Stride----------------- 
 ---------Width-------------    注:Width是图片(BGR作为一个单位)宽度

  • 上一篇Dotnet:

  • 下一篇Dotnet:
  • 最 新 热 门
     用VB.net2008编写屏幕抓捕程序
     用VB.net2008编写幻灯片程序
     VB.net2008创建发送与接收端程序
     在VB.NET中使用动态属性解析
     ASP.NET中图象处理过程详解
     解析VB.NET中的面向对象编程特征
     VisualC#中实现DB2数据库编程
     在VisualC#中用ListView显示数据记录
     用Dojo和Ajax创建可重用和可重新发布
     ASP.NET网络编程中经常用到的27个函数集
    最 新 推 荐
     利用C#实现超酷动态图像按钮
     C#开发智能手机游戏推箱子软件
     C# 索引器实战开发学习笔记
     编程中使用C#的BitmapData实例
     C# 制作以动画的方式显示图像
     如何构造一个C#语言的爬虫蜘蛛程序
     C#编程轻松实现对文件的操作技巧
     C#如何取硬件标志代码
     C#中将Big5繁体转换简体GB2312的代码
     C#线程池的实现
    相 关 文 章

    在VB.NET中使用动态属性解析
    解析VB.NET中的面向对象编程特征
    ASP.NET网络编程中经常用到的27个函数集
    VB.NET编程中的字节校验例子
    在VB.NET编程中使用数组
    使用LINQ来简化编程的7个技巧
    Visual C#中实现DB2数据库的编程实例
    Visual C#实现DB2数据库的编程例子
    Visual C# 编程操作Excel
    程序员成为成为编程高手的二十二条军规

    | 设为首页 | 加入收藏 | 联系站长 | 友情链接 | 版权申明 | 网站公告

     

    Copyright 2006-2008 pcjx.com All Rights Reserved
    电脑技巧 版权所有 粤ICP备06059145号 地图
    门市地址:广东省佛山市南海区黄岐黄海路133号
    本网站所有内容未经许可不得转载或做其他使用