原链接:https://blog.csdn.net/yangyikun0428/article/details/53771596

在对Bitmap图片操作的时候,有时需要用到获取或设置像素颜色方法:GetPixel 和 SetPixel,

如果直接对这两个方法进行操作的话速度很慢,这里我们可以通过把数据提取出来操作,然后操作完在复制回去可以加快访问速度

其实对Bitmap的访问还有两种方式,一种是内存法,一种是指针法

1、内存法

  这里定义一个类LockBitmap,通过把Bitmap数据拷贝出来,在内存上直接操作,操作完成后在拷贝到Bitmap中

        public class LockBitmap{Bitmap source = null;IntPtr Iptr = IntPtr.Zero;BitmapData bitmapData = null;public byte[] Pixels { get; set; }public int Depth { get; private set; }public int Width { get; private set; }public int Height { get; private set; }public LockBitmap(Bitmap source){this.source = source;}/// <summary>/// Lock bitmap data/// </summary>public void LockBits(){try{// Get width and height of bitmapWidth = source.Width;Height = source.Height;// get total locked pixels countint PixelCount = Width * Height;// Create rectangle to lockRectangle rect = new Rectangle(0, 0, Width, Height);// get source bitmap pixel format sizeDepth = System.Drawing.Bitmap.GetPixelFormatSize(source.PixelFormat);// Check if bpp (Bits Per Pixel) is 8, 24, or 32if (Depth != 8 && Depth != 24 && Depth != 32){throw new ArgumentException("Only 8, 24 and 32 bpp images are supported.");}// Lock bitmap and return bitmap databitmapData = source.LockBits(rect, ImageLockMode.ReadWrite,source.PixelFormat);// create byte array to copy pixel valuesint step = Depth / 8;Pixels = new byte[PixelCount * step];Iptr = bitmapData.Scan0;// Copy data from pointer to arrayMarshal.Copy(Iptr, Pixels, 0, Pixels.Length);}catch (Exception ex){throw ex;}}/// <summary>/// Unlock bitmap data/// </summary>public void UnlockBits(){try{// Copy data from byte array to pointerMarshal.Copy(Pixels, 0, Iptr, Pixels.Length);// Unlock bitmap datasource.UnlockBits(bitmapData);}catch (Exception ex){throw ex;}}/// <summary>/// Get the color of the specified pixel/// </summary>/// <param name="x"></param>/// <param name="y"></param>/// <returns></returns>public Color GetPixel(int x, int y){Color clr = Color.Empty;// Get color components countint cCount = Depth / 8;// Get start index of the specified pixelint i = ((y * Width) + x) * cCount;if (i > Pixels.Length - cCount)throw new IndexOutOfRangeException();if (Depth == 32) // For 32 bpp get Red, Green, Blue and Alpha{byte b = Pixels[i];byte g = Pixels[i + 1];byte r = Pixels[i + 2];byte a = Pixels[i + 3]; // aclr = Color.FromArgb(a, r, g, b);}if (Depth == 24) // For 24 bpp get Red, Green and Blue{byte b = Pixels[i];byte g = Pixels[i + 1];byte r = Pixels[i + 2];clr = Color.FromArgb(r, g, b);}if (Depth == 8)// For 8 bpp get color value (Red, Green and Blue values are the same){byte c = Pixels[i];clr = Color.FromArgb(c, c, c);}return clr;}/// <summary>/// Set the color of the specified pixel/// </summary>/// <param name="x"></param>/// <param name="y"></param>/// <param name="color"></param>public void SetPixel(int x, int y, Color color){// Get color components countint cCount = Depth / 8;// Get start index of the specified pixelint i = ((y * Width) + x) * cCount;if (Depth == 32) // For 32 bpp set Red, Green, Blue and Alpha{Pixels[i] = color.B;Pixels[i + 1] = color.G;Pixels[i + 2] = color.R;Pixels[i + 3] = color.A;}if (Depth == 24) // For 24 bpp set Red, Green and Blue{Pixels[i] = color.B;Pixels[i + 1] = color.G;Pixels[i + 2] = color.R;}if (Depth == 8)// For 8 bpp set color value (Red, Green and Blue values are the same){Pixels[i] = color.B;}}}

  使用:先锁定Bitmap,然后通过Pixels操作颜色对象,最后释放锁,把数据更新到Bitmap中

            string file = @"C:\test.jpg";Bitmap bmp = new Bitmap(Image.FromFile(file));LockBitmap lockbmp = new LockBitmap(bmp);//锁定Bitmap,通过Pixel访问颜色lockbmp.LockBits();//获取颜色Color color = lockbmp.GetPixel(10, 10);//从内存解锁Bitmaplockbmp.UnlockBits();

2、指针法

  这种方法访问速度比内存法更快,直接通过指针对内存进行操作,不需要进行拷贝,但是在C#中直接通过指针操作内存是不安全的,所以需要在代码中加入unsafe关键字,在生成选项中把允许不安全代码勾上,才能编译通过

  这里定义成PointerBitmap类

            public class PointBitmap{Bitmap source = null;IntPtr Iptr = IntPtr.Zero;BitmapData bitmapData = null;public int Depth { get; private set; }public int Width { get; private set; }public int Height { get; private set; }public PointBitmap(Bitmap source){this.source = source;}public void LockBits(){try{// Get width and height of bitmapWidth = source.Width;Height = source.Height;// get total locked pixels countint PixelCount = Width * Height;// Create rectangle to lockRectangle rect = new Rectangle(0, 0, Width, Height);// get source bitmap pixel format sizeDepth = System.Drawing.Bitmap.GetPixelFormatSize(source.PixelFormat);// Check if bpp (Bits Per Pixel) is 8, 24, or 32if (Depth != 8 && Depth != 24 && Depth != 32){throw new ArgumentException("Only 8, 24 and 32 bpp images are supported.");}// Lock bitmap and return bitmap databitmapData = source.LockBits(rect, ImageLockMode.ReadWrite,source.PixelFormat);//得到首地址unsafe{Iptr = bitmapData.Scan0;//二维图像循环}}catch (Exception ex){throw ex;}}public void UnlockBits(){try{source.UnlockBits(bitmapData);}catch (Exception ex){throw ex;}}public Color GetPixel(int x, int y){unsafe{byte* ptr = (byte*)Iptr;ptr = ptr + bitmapData.Stride * y;ptr += Depth * x / 8;Color c = Color.Empty;if (Depth == 32){int a = ptr[3];int r = ptr[2];int g = ptr[1];int b = ptr[0];c = Color.FromArgb(a, r, g, b);}else if (Depth == 24){int r = ptr[2];int g = ptr[1];int b = ptr[0];c = Color.FromArgb(r, g, b);}else if (Depth == 8){int r = ptr[0];c = Color.FromArgb(r, r, r);}return c;}}public void SetPixel(int x, int y, Color c){unsafe{byte* ptr = (byte*)Iptr;ptr = ptr + bitmapData.Stride * y;ptr += Depth * x / 8;if (Depth == 32){ptr[3] = c.A;ptr[2] = c.R;ptr[1] = c.G;ptr[0] = c.B;}else if (Depth == 24){ptr[2] = c.R;ptr[1] = c.G;ptr[0] = c.B;}else if (Depth == 8){ptr[2] = c.R;ptr[1] = c.G;ptr[0] = c.B;}}}}

使用方法这里就不列出来了,跟上面的LockBitmap类似

解决 C# GetPixel 和 SetPixel 效率问题相关推荐

  1. 解决 C# GetPixel 和 SetPixel 效率问题(转)

    在对Bitmap图片操作的时候,有时需要用到获取或设置像素颜色方法:GetPixel 和 SetPixel, 如果直接对这两个方法进行操作的话速度很慢,这里我们可以通过把数据提取出来操作,然后操作完在 ...

  2. 有人说中文编辑是解决中国程序员编程效率的秘密武器,请问他是一个银弹吗?...

    一."银弹" 首先在这里解释一下"银弹"的概念,顾名思义就是银质的子弹(Silver Bullet),是古老的欧洲民间传说中能杀死狼人的利器.当然现实中是没有狼 ...

  3. “中文编程”会是解决中国程序员编程效率的秘密武器,成为中国软件工程的“银弹”么?...

    一."银弹" 首先在这里解释一下"银弹"的概念,顾名思义就是银质的子弹(Silver Bullet),是古老的欧洲民间传说中能杀死狼人的利器.当然现实中是没有狼 ...

  4. bitblt和getpixel哪个更效率

    bitblt和getpixel哪个更效率 Delphi / Windows SDK/API http://www.delphi2007.net/DelphiMultimedia/html/delphi ...

  5. 【支小蜜智慧食堂】随时查账单,解决学校食堂点餐效率低问题

    随时查账单 原来学生在学校食堂的消费只是在餐厅本地计算机上存储,需要由食堂管理人员上传后,家长才能看到学生在学校的就餐情况,总是不能满足家长的需求;改造后的支小蜜智慧食堂,学生消费明细实时推送到家长的 ...

  6. 有人认为,“中文编程”是解决中国程序员编程效率的秘密武器,请问它是一个“银弹”么?...

    银色子弹(英文:Silver Bullet),或者称"银弹""银质子弹",指由纯银质或镀银的子弹.在欧洲民间传说及19世纪以来哥特小说风潮的影响下,银色子弹往往 ...

  7. 【uniapp】使用扫码插件,解决uni.scanCode扫码效率低的问题

    1. 背景   uniapp 中自带的二维码扫描的 API 是 uni.scanCode,但有如下问题: 二维码扫描的效率不高,有些需要扫2秒左右 较小或模糊的一些二维码无法识别出来,多次扫同样的一个 ...

  8. 回溯法解决01背包-非递归算法-效率低

    http://acm.zua.edu.cn/problem.php?cid=1025&pid=24 解题思路: 物体的个数为Num,背包的体积限制为Volum 物品的体积是v[1].v[2]. ...

  9. mysql海豚工具不提示,Navicat使用常见的两个问题及解决方法,提高开发效率

    Navicat使用常见问题 在我们日常开发过程中,一般不会直接使用命令行来操作 MYSQL 数据库,而会选择一些图形化界面去帮助我们来进行此类操作,常用的有:SQLyog(Logo也是小海豚),Nav ...

最新文章

  1. 3月第一周几个要处理的问题
  2. LINQ to SQL语句(4)之Join
  3. java中自定义比较器_Java中的比较器:自定义规则!!!
  4. python matplotlib显示图片_Python OpenCV ——Matplotlib显示图片
  5. Java 洛谷 P1089 津津的储蓄计划讲解
  6. 短信猫编程的一些资料1(At指令发送短信)
  7. jquery 回车事件
  8. 一文理清Cookie、Session、Token
  9. redis笔记——redis事务及锁应用
  10. python写一个木马_Python编写简易木马程序 - 博客频道 - CSDN.NET
  11. swift混编调用oc编写的Xib UIView出现[Storyboard] Unknown class in Interface Builder file.问题的解决
  12. SIGAR - System Information Gatherer And Reporter
  13. Titantic乘客生还预测数据分析报告—基于python实现
  14. 【Python从入门到精通】(三)Python的编码规范,标识符知多少?
  15. Java岗大厂面试百日冲刺 - 日积月累,每日三题【Day22】—— 并发编程2
  16. java.io.FileNotFoundException: file:/xxx/xxx.jar!/BOOT-INF/classes!/xxx.xlsx (没有那个文件或目录)
  17. BLOCK层代码分析(1)数据的组织BIO
  18. 【智能优化算法】基于倭黑猩猩优化算法求解单目标优化问题附matlab代码
  19. 浏览器发送请求过程解析
  20. Springboot使用Mapstruct拷贝对象,集成swagger2

热门文章

  1. Cesium变换3DTiles的位置(平移旋转缩放)
  2. js正则表达式将中文标点转为英文标点
  3. 【MATLAB】进阶绘图 ( Pie Chart 饼图 | pie 函数 | 三维饼图 | pie3 函数 )
  4. 中国工程院院士、中国人工智能学会理事长李德毅:人工智能研究新进展
  5. 一个老程序员的一些职场经验分享
  6. indesign选中不了图片删除_图片神器XnView教程、方法和技巧汇总
  7. 优质的草图大师素材 草图66!
  8. python练习题——十大歌手
  9. 202020 公文系统安装技巧
  10. Python——绑定与方法调用