知识大全 使用C#的BitmapData 编程实例
Posted 字节
篇首语:同时赶两只兔,一只也捉不到。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 使用C#的BitmapData 编程实例相关的知识,希望对你有一定的参考价值。
使用C#的BitmapData 编程实例 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!
最近要转开发平台 正研究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 Format bppRgb);
BitmapData dataIn = m_Bmp LockBits(new Rectangle( w h) ImageLockMode ReadOnly PixelFormat Format bppRgb); BitmapData dataOut = bmpOut LockBits(new Rectangle( w h) ImageLockMode ReadWrite PixelFormat Format bppRgb);
unsafe byte* pIn = (byte*)(dataIn Scan ToPointer()); byte * pOut = (byte*)(dataOut Scan ToPointer());
for (int y = ; y < dataIn Height; y++) for (int x = ; x < dataIn Width; x++)
pOut[ ] = (byte)( pIn[ ]); pOut[ ] = (byte)( pIn[ ]); pOut[ ] = (byte)( pIn[ ]);
pIn += ; pOut += ;
pIn += dataIn Stride dataIn Width * ; pOut += dataOut Stride dataOut Width * ;
bmpOut UnlockBits(dataOut); m_Bmp UnlockBits(dataIn);
貌似比Delphi复杂得多 难道我真的天生对指针过敏?还是Delphi的比较好理解 就是扫描每一行 然后对当前像素点的三个分量做处理 非常方便 而且C#代码中的Stride是个什么东东? 查找了不少资料 现在我是这么理解的 假设有一张图片宽度为 因为是Format bppRgb格式(每像素 字节 在以下的讨论中 除非特别说明 否则Bitmap都被认为是 位RGB)的 显然 每一行需要 * = 个字节存储 对于Bitmap就是如此 但对于BitmapData 虽然BitmapData Width还是等于Bitmap Width 但大概是出于显示性能的考虑 每行的实际的字节数将变成大于等于它的那个离它最近的 的整倍数 此时的实际字节数就是Stride 就此例而言 不是 的整倍数 而比 大的离 最近的 的倍数是 所以这个BitmapData Stride = 显然 当宽度本身就是 的倍数时 BitmapData Stride = Bitmap Width * 画个图可能更好理解
R G B 分别代表 个原色分量字节 BGR就表示一个像素 为了看起来方便我在每个像素之间插了个空格 实际上是没有的 X表示补足 的倍数而自动插入的字节 为了符合人类的阅读习惯我分行了 其实在计算机内存中应该看成连续的一大段
Scan Stride Width 注 Width是图片(BGR作为一个单位)宽度 BGR BGR BGR BGR BGR BGR XX BGR BGR BGR BGR BGR BGR XX
现在应该很好理解了 首先用 BitmapData Scan 找到第 个像素的第 个分量的地址 这个地址指向的是个byte类型 所以当时定义为byte* pIn 行扫描时 在当前指针位置(不妨看成当前像素的第 个颜色分量)连续取出三个值( 个原色分量 注意 代表的次序是B G R 在取指针指向的值时 貌似p[n]和p += n再取p[ ]是等价的) 然后下移 个位置(pIn += 看成指到下一个像素的第 个颜色分量) 做过Bitmap Width次操作后 就到达了Bitmap Width * 的位置 应该要跳过图中标记为X的字节了(共有Stride Width * 个字节) 代码中就是 pIn += dataIn Stride dataIn Width * ;
跳过以后指针就到达下行的第 个像素了 按照此算法 一共需要做Bitmap Height次行扫描(代码就是 for (int y = ; y < dataIn Height; y++))
cha138/Article/program/net/201311/14981相关参考
C#多线程编程实例 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 问题的提出 所谓单个写入程序
C#高级编程读写文本文件实例 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 理论上可以使用Fil
知识大全 Visual C#中实现DB2数据库的编程实例[1]
VisualC#中实现DB2数据库的编程实例[1] 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!
知识大全 Visual C#中实现DB2数据库的编程实例[3]
VisualC#中实现DB2数据库的编程实例[3] 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!
知识大全 Visual C#中实现DB2数据库的编程实例[2]
VisualC#中实现DB2数据库的编程实例[2] 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!t
一预定义数据类型 char字符类型单引号例如charx=this; c#中的每个数据类型其实就是一个静态的类每个变量都是一个类的实例 例如将int型的数据转化为stringstringx=i
C#语言学习:C#数据报编程之测试程序 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! C#中自定
C#编程规范 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 一命名 用pascal规则来命名方
提高C#编程水平的50个要诀 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 提高C#编程水平的个
叩开C#之门系列之C#与面向对象编程语言 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! C#是纯