知识大全 编程中使用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/14828相关参考
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
C#中COM操作(一)---实例化 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 用C#做Win
深入解析C#编程中的事件 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 一个事件是一个使对象或类
C#中COM操作(一)---实例化[1] 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 用C#做
C#编程实现在Excel文档中搜索文本 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!lishixi
C#中COM操作(一)---实例化[2] 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 直接声明