许多图像处理任务即时是最简单的文件类型转换,例如从32位深度到8位深度的格式转化,直接获得像素阵列要比使用GetPixel和SetPixel等方法的效率高得多。

你可能会发现DotNet采用托管机制,大多数情况下微软会推荐你使用托管代码,理由是便捷和安全。实际应用中,直接操作内存中的数据块是很少见的,尽管如此,图像处理恰恰是这类为数不多的情况之一,因为使用托管代码的效率低的难以忍受,特别是对巨幅图像来说,在此,我们讨论一下一种新的方法。

如何使用非托管代码是因语言而异的,在C#中我们可以通过unsafe关键字来调用指针,从而直接操作内存中的位图数据;VB则使用Marshal类中的方法,它会导致一部分的性能损失,因此效率不如前者。

锁定比特流

Bitmap类使用LockBits和UnLockBits方法来将位图的数据矩阵保存在内存中、直接对它进行操作,最后用修改后的数据代替位图中的原始数据。LockBits返回以各BitmapData的类用已描述数据在已锁定的矩阵中的位置和分布。

BitmapData类包括以下几个重要的属性:

  • Scan0:数据矩阵在内存中的地址。

  • Stride:数据矩阵中的行宽,以byte为单位。可能会扩展几个Byte,后面会介绍。

  • PixelFormat:像素格式,这对矩阵中字节的定位很重要。

  • Width:位图的宽度。

  • Height:位图的高度。

具体关系见下图:

如上图所示,stride属性表示位图数据矩阵的行宽,以byte为单位。出于效率考虑,矩阵的行宽并非刚好是每行像素数的整数倍,系统往往会将其封装成4的整数倍。举例来说,对于一幅24位深17像素宽的图像,其stride属性为52;每行的数据量为17*3=51,系统将其自动封装一个字节,所以它的stride为52byte(或13*4byte)。对于一幅17像素宽的4位索引图,其stride为12,其中9byte(准确地说是8.5个byte)用来记录数据信息,每行再自动添加3(3.5)个byte保证其为4的整数倍。

具体数据的分布因其pixel format而异。24位深的图像每隔3个byte包含一组RGB信息;32位深的图像每隔4个byte包含一组RGBA信息。那些每个字节包含多个像素的pixel format,比如4位索引图像或1位索引图像,必须经过仔细处理,从而保证同一字节中的相邻byte不会混淆。

指针的准确定位

  • 32位RGB:假设X、Y为位图中像素的坐标,则其在内存中的地址为scan0+Y*stride+X*4。此时指针指向蓝色,其后分别是绿色、红色,alpha分量。

  • 24位RGB:scan0+Y*stride+X*3。此时指针指向蓝色,其后分别是绿色和红色。

  • 8位索引:scan0+Y*stride+X。当前指针指向图像的调色盘。

  • 4位索引:scan0+Y*stride+(X/2)。当前指针所指的字节包括两个像素,通过高位和低位索引16色调色盘,其中高位表示左边的像素,低位表示右边的像素。

  • 1位索引:scan0+Y*stride+X/8。当前指针所指的字节中的每一位都表示一个像素的索引颜色,调色盘为两色,最左边的像素为8,最右边的像素为0。

像素间使用迭代器

下面这个范例将一幅32位深的图像中所有像素的蓝色分量设为最大(255):

BitmapData bmd=bm.LockBits(new Rectangle(0, 0, 10, 10),  System.Drawing.Imaging.ImageLockMode.ReadOnly, bm.PixelFormat);

int PixelSize=4;

for(int y=0; y<bmd.Height; y++)

{

byte* row=(byte *)bmd.Scan0+(y*bmd.Stride);

for(int x=0; x<bmd.Width; x++)

{

row[x*PixelSize]=255;

}

}

处理4位索引图,高低位应分开处理,代码如下:

int offset = (y * bmd.Stride) + (x >> 1);

byte currentByte = ((byte *)bmd.Scan0)[offset];

if((x&1) == 1)

{

currentByte &= 0xF0;

currentByte |= (byte)(colorIndex & 0x0F);

}

else

{

currentByte &= 0x0F;

currentByte |= (byte)(colorIndex << 4);

}

((byte *)bmd.Scan0)[offset]=currentByte;

处理1位索引的代码:

byte* p=(byte*)bmd.Scan0.ToPointer();

int index=y*bmd.Stride+(x>>3);

byte mask=(byte)(0x80>>(x&0x7));

if(pixel)

p[index]|=mask;

else

p[index]&=(byte)(mask^0xff);

最后在进行完所有处理后马不要忘记使用Unlockbits命令解锁。

原文在这里http://blog.sina.com.cn/s/blog_4e3e2ce4010009on.html

转载于:https://www.cnblogs.com/xiashengwang/p/4208333.html

【转】使用lockbits方法处理图像相关推荐

  1. 空间金字塔方法表示图像

    注:本学习笔记是自己的理解,如有错误的地方,请大家指正,共同学习进步. 本文学习自CVPR论文<Discriminative Spatial Pyramid>.<Discrimina ...

  2. ITK:使用分水岭Watershed方法对图像进行分割

    ITK:使用分水岭Watershed方法对图像进行分割 内容提要 输出结果 C++实现代码 内容提要 本示例说明了如何使用分水岭方法对图像进行分割. 输出结果 C++实现代码 #include &qu ...

  3. 运用滤波反投影的方法对图像进行重建matlab仿真

    目录 1.算法描述 2.仿真效果预览 3.MATLAB部分代码预览 4.完整MATLAB程序 1.算法描述 直接由正弦图得到反投影图像,会存在严重的模糊,这是早期 CT 系统所存在的问题.傅立叶中心切 ...

  4. HTML5系列代码:使用三种方法插入图像

    drawImage() 方法在画布上绘制图像.画布或视频. drawImage() 方法也能够绘制图像的某些部分,以及/或者增加或减少图像的尺寸. <!DOCTYPE HTML> < ...

  5. MATLAB利用均值滤波的方法去除图像的噪声,将滤除噪声前后的图像输出。

    利用均值滤波的方法去除图像的噪声,将滤除噪声前后的图像输出.调用imfilter函数滤除图像噪声并输出,对比调用MATLAB函数去噪的图像与自己所编写程序去噪后的图像进行对比. clc; A=imre ...

  6. html图片上面怎么 画,HTML5使用drawImage()方法绘制图像

    一.绘制图像 使用drawImage()方法绘制图像.绘图环境提供了该方法的三个不同版本. drawImage(image,x,y) : 在canvas中(x,y)处绘制图片. drawImage(i ...

  7. python统计图片的纹理信息_python实现LBP方法提取图像纹理特征实现分类

    题目描述 这篇博文是数字图像处理的大作业. 题目描述:给定40张不同风格的纹理图片,大小为512*512,要求将每张图片分为大小相同的9块,利用其中的5块作为训练集,剩余的4块作为测试集,构建适当的模 ...

  8. 用python绘制熊猫图案_使用pandas的DataFrame的plot方法绘制图像的实例

    使用了pandas的Series方法绘制图像体验之后感觉直接用matplotlib的功能好用了不少,又试用了DataFrame的方法之后发现这个更加人性化. 写代码如下: from pandas im ...

  9. matlab的边缘检测方法,常用图像边缘检测方法及Matlab研究

    2011 年 2 月 15 日第 34 卷第 4 期 现代电子技术 Modern Electronics Technique Feb. 2011 Vol. 34 No. 4 常用图像边缘检测方法及 M ...

最新文章

  1. C语言编写的PHP框架--yaf入门编程
  2. Python脚本程序实现搜索文本文件内容
  3. php java if_phpjava(二)
  4. 【学习笔记】11、循环语句—while
  5. C++和 C 的区别
  6. icoding复习3
  7. HTML+CSS+JS实现 ❤️从亮到暗图片滤镜特效❤️
  8. Java中使用OpenSSL生成的RSA公私钥进行数据加解密
  9. 【题解】SCOI2009围豆豆
  10. djangosave保存数据太慢_PaddlePaddle从入门到炼丹八——模型的保存与使用
  11. FxFactory pro 8 for Mac(视觉特效包处理工具)直装版
  12. 利用python进行身份证号码大全_身份证号码设置显示格式,我用了最笨的办法,你有什么好办法吗?...
  13. 王阳明的智慧:如何让职场从“举步维艰”到“平步青云”?
  14. php 图片外链限制,将新浪微博图床图片保存到本地解决限制外链的方法
  15. 计算机网络连接黄感叹号,电脑连接路由器网络连接显示黄色感叹号的解决办法...
  16. 英语构词法软件wordformation发布全新1.0版本
  17. 关于卷积核大小的论文与思路
  18. 限制guest账号访问硬盘权限
  19. 怎么把已经初始化的字符数组设置为空?
  20. 《MySQL数据库用户模块需求分析》

热门文章

  1. ext 不能修改 输入框_在extjs中,如何用method改变textfield中inputType的问题
  2. MySQL聚集索引详解_MySQL innodb 聚集索引的概念与使用教程
  3. /plus/recommend.php sql注入漏洞,DedeCMS 全版本通杀SQL注入漏洞利用代码及工具 -
  4. python微控制器编程从零开始 pdf_Python极客项目编程_(美)Mahesh Venkitachalam.pdf
  5. java培训学费_太原java培训班价格表
  6. 20210602:力扣第243周周赛(下)
  7. 20200127:(leetcode)四数之和(动态图解)
  8. dataframe 如何增加新的索引_带你领略pandas中多表之间如何处理
  9. python批量移动文件_用python批量移动文件
  10. docker实践第二版pdf 网盘_【漫画】什么是 docker?docker 应用场景解析