1. #region 灰度处理
  2. /// <summary>
  3. /// 将源图像灰度化,并转化为8位灰度图像。
  4. /// </summary>
  5. /// <param name="original"> 源图像。 </param>
  6. /// <returns> 8位灰度图像。 </returns>
  7. public static Bitmap RgbToGrayScale(Bitmap original)
  8. {
  9. if (original != null)
  10. {
  11. // 将源图像内存区域锁定
  12. Rectangle rect = new Rectangle(, , original.Width, original.Height);
  13. BitmapData bmpData = original.LockBits(rect, ImageLockMode.ReadOnly,
  14. PixelFormat.Format24bppRgb);
  15.  
  16. // 获取图像参数
  17. int width = bmpData.Width;
  18. int height = bmpData.Height;
  19. int stride = bmpData.Stride; // 扫描线的宽度,比实际图片要大
  20. int offset = stride - width * ; // 显示宽度与扫描线宽度的间隙
  21. IntPtr ptr = bmpData.Scan0; // 获取bmpData的内存起始位置的指针
  22. int scanBytesLength = stride * height; // 用stride宽度,表示这是内存区域的大小
  23.  
  24. // 分别设置两个位置指针,指向源数组和目标数组
  25. int posScan = , posDst = ;
  26. byte[] rgbValues = new byte[scanBytesLength]; // 为目标数组分配内存
  27. Marshal.Copy(ptr, rgbValues, , scanBytesLength); // 将图像数据拷贝到rgbValues中
  28. // 分配灰度数组
  29. byte[] grayValues = new byte[width * height]; // 不含未用空间。
  30. // 计算灰度数组
  31.  
  32. byte blue, green, red, YUI;
  33.  
  34. for (int i = ; i < height; i++)
  35. {
  36. for (int j = ; j < width; j++)
  37. {
  38.  
  39. blue = rgbValues[posScan];
  40. green = rgbValues[posScan + ];
  41. red = rgbValues[posScan + ];
  42. YUI = (byte)(0.229 * red + 0.587 * green + 0.144 * blue);
  43. //grayValues[posDst] = (byte)((blue + green + red) / 3);
  44. grayValues[posDst] = YUI;
  45. posScan += ;
  46. posDst++;
  47.  
  48. }
  49. // 跳过图像数据每行未用空间的字节,length = stride - width * bytePerPixel
  50. posScan += offset;
  51. }
  52.  
  53. // 内存解锁
  54. Marshal.Copy(rgbValues, , ptr, scanBytesLength);
  55. original.UnlockBits(bmpData); // 解锁内存区域
  56.  
  57. // 构建8位灰度位图
  58. Bitmap retBitmap = BuiltGrayBitmap(grayValues, width, height);
  59. return retBitmap;
  60. }
  61. else
  62. {
  63. return null;
  64. }
  65. }
  66.  
  67. /// <summary>
  68. /// 用灰度数组新建一个8位灰度图像。
  69. /// </summary>
  70. /// <param name="rawValues"> 灰度数组(length = width * height)。 </param>
  71. /// <param name="width"> 图像宽度。 </param>
  72. /// <param name="height"> 图像高度。 </param>
  73. /// <returns> 新建的8位灰度位图。 </returns>
  74. private static Bitmap BuiltGrayBitmap(byte[] rawValues, int width, int height)
  75. {
  76. // 新建一个8位灰度位图,并锁定内存区域操作
  77. Bitmap bitmap = new Bitmap(width, height, PixelFormat.Format8bppIndexed);
  78. BitmapData bmpData = bitmap.LockBits(new Rectangle(, , width, height),
  79. ImageLockMode.WriteOnly, PixelFormat.Format8bppIndexed);
  80.  
  81. // 计算图像参数
  82. int offset = bmpData.Stride - bmpData.Width; // 计算每行未用空间字节数
  83. IntPtr ptr = bmpData.Scan0; // 获取首地址
  84. int scanBytes = bmpData.Stride * bmpData.Height; // 图像字节数 = 扫描字节数 * 高度
  85. byte[] grayValues = new byte[scanBytes]; // 为图像数据分配内存
  86.  
  87. // 为图像数据赋值
  88. int posSrc = , posScan = ; // rawValues和grayValues的索引
  89. for (int i = ; i < height; i++)
  90. {
  91. for (int j = ; j < width; j++)
  92. {
  93. grayValues[posScan++] = rawValues[posSrc++];
  94. }
  95. // 跳过图像数据每行未用空间的字节,length = stride - width * bytePerPixel
  96. posScan += offset;
  97. }
  98.  
  99. // 内存解锁
  100. Marshal.Copy(grayValues, , ptr, scanBytes);
  101. bitmap.UnlockBits(bmpData); // 解锁内存区域
  102.  
  103. // 修改生成位图的索引表,从伪彩修改为灰度
  104. ColorPalette palette;
  105. // 获取一个Format8bppIndexed格式图像的Palette对象
  106. using (Bitmap bmp = new Bitmap(, , PixelFormat.Format8bppIndexed))
  107. {
  108. palette = bmp.Palette;
  109. }
  110. for (int i = ; i < ; i++)
  111. {
  112. palette.Entries[i] = Color.FromArgb(i, i, i);
  113. }
  114. // 修改生成位图的索引表
  115. bitmap.Palette = palette;
  116.  
  117. return bitmap;
  118. }
  119. #endregion

C#图片二值化处理(位深度8→位深度1)

  1. #region 二值化
  2. /*
  3. 1位深度图像 颜色表数组255个元素 只有用前两个 0对应0 1对应255
  4. 1位深度图像每个像素占一位
  5. 8位深度图像每个像素占一个字节 是1位的8倍
  6. */
  7. /// <summary>
  8. /// 将源灰度图像二值化,并转化为1位二值图像。
  9. /// </summary>
  10. /// <param name="bmp"> 源灰度图像。 </param>
  11. /// <returns> 1位二值图像。 </returns>
  12. public static Bitmap GTo2Bit(Bitmap bmp)
  13. {
  14. if (bmp != null)
  15. {
  16. // 将源图像内存区域锁定
  17. Rectangle rect = new Rectangle(, , bmp.Width, bmp.Height);
  18. BitmapData bmpData = bmp.LockBits(rect, ImageLockMode.ReadOnly,
  19. PixelFormat.Format8bppIndexed);
  20.  
  21. // 获取图像参数
  22. int leng, offset_1bit = ;
  23. int width = bmpData.Width;
  24. int height = bmpData.Height;
  25. int stride = bmpData.Stride; // 扫描线的宽度,比实际图片要大
  26. int offset = stride - width; // 显示宽度与扫描线宽度的间隙
  27. IntPtr ptr = bmpData.Scan0; // 获取bmpData的内存起始位置的指针
  28. int scanBytesLength = stride * height; // 用stride宽度,表示这是内存区域的大小
  29. if (width % == )
  30. {
  31. leng = width / ;
  32. }
  33. else
  34. {
  35. leng = width / + ( - (width / % ));
  36. if (width % != )
  37. {
  38. offset_1bit = leng - width / ;
  39. }
  40. else
  41. {
  42. offset_1bit = leng - width / ;
  43. }
  44. }
  45.  
  46. // 分别设置两个位置指针,指向源数组和目标数组
  47. int posScan = , posDst = ;
  48. byte[] rgbValues = new byte[scanBytesLength]; // 为目标数组分配内存
  49. Marshal.Copy(ptr, rgbValues, , scanBytesLength); // 将图像数据拷贝到rgbValues中
  50. // 分配二值数组
  51. byte[] grayValues = new byte[leng * height]; // 不含未用空间。
  52. // 计算二值数组
  53. int x, v, t = ;
  54. for (int i = ; i < height; i++)
  55. {
  56. for (x = ; x < width; x++)
  57. {
  58. v = rgbValues[posScan];
  59. t = (t << ) | (v > ? : );
  60.  
  61. if (x % == )
  62. {
  63. grayValues[posDst] = (byte)t;
  64. posDst++;
  65. t = ;
  66. }
  67. posScan++;
  68. }
  69.  
  70. if ((x %= ) != )
  71. {
  72. t <<= - x;
  73. grayValues[posDst] = (byte)t;
  74. }
  75. // 跳过图像数据每行未用空间的字节,length = stride - width * bytePerPixel
  76. posScan += offset;
  77. posDst += offset_1bit;
  78. }
  79.  
  80. // 内存解锁
  81. Marshal.Copy(rgbValues, , ptr, scanBytesLength);
  82. bmp.UnlockBits(bmpData); // 解锁内存区域
  83.  
  84. // 构建1位二值位图
  85. Bitmap retBitmap = twoBit(grayValues, width, height);
  86. return retBitmap;
  87. }
  88. else
  89. {
  90. return null;
  91. }
  92. }
  93.  
  94. /// <summary>
  95. /// 用二值数组新建一个1位二值图像。
  96. /// </summary>
  97. /// <param name="rawValues"> 二值数组(length = width * height)。 </param>
  98. /// <param name="width"> 图像宽度。 </param>
  99. /// <param name="height"> 图像高度。 </param>
  100. /// <returns> 新建的1位二值位图。 </returns>
  101. private static Bitmap twoBit(byte[] rawValues, int width, int height)
  102. {
  103. // 新建一个1位二值位图,并锁定内存区域操作
  104. Bitmap bitmap = new Bitmap(width, height, PixelFormat.Format1bppIndexed);
  105. BitmapData bmpData = bitmap.LockBits(new Rectangle(, , width, height),
  106. ImageLockMode.WriteOnly, PixelFormat.Format1bppIndexed);
  107.  
  108. // 计算图像参数
  109. int offset = bmpData.Stride - bmpData.Width / ; // 计算每行未用空间字节数
  110. IntPtr ptr = bmpData.Scan0; // 获取首地址
  111. int scanBytes = bmpData.Stride * bmpData.Height; // 图像字节数 = 扫描字节数 * 高度
  112. byte[] grayValues = new byte[scanBytes]; // 为图像数据分配内存
  113.  
  114. // 为图像数据赋值
  115. int posScan = ; // rawValues和grayValues的索引
  116. for (int i = ; i < height; i++)
  117. {
  118. for (int j = ; j < bmpData.Width / ; j++)
  119. {
  120. grayValues[posScan] = rawValues[posScan];
  121. posScan++;
  122. }
  123. // 跳过图像数据每行未用空间的字节,length = stride - width * bytePerPixel
  124. posScan += offset;
  125. }
  126.  
  127. // 内存解锁
  128. Marshal.Copy(grayValues, , ptr, scanBytes);
  129. bitmap.UnlockBits(bmpData); // 解锁内存区域
  130.  
  131. // 修改生成位图的索引表
  132. ColorPalette palette;
  133. // 获取一个Format8bppIndexed格式图像的Palette对象
  134. using (Bitmap bmp = new Bitmap(, , PixelFormat.Format1bppIndexed))
  135. {
  136. palette = bmp.Palette;
  137. }
  138. for (int i = ; i < ; i = +)
  139. {
  140. palette.Entries[i] = Color.FromArgb(i, i, i);
  141. }
  142. // 修改生成位图的索引表
  143. bitmap.Palette = palette;
  144.  
  145. return bitmap;
  146. }
  147. #endregion

C#图片灰度处理(位深度24→位深度8)的更多相关文章

  1. C#图片灰度处理(位深度24→位深度8),用灰度数组byte[]新建一个8位灰度图像Bitmap 。

    原文:C#图片灰度处理(位深度24→位深度8) #region 灰度处理 /// <summary> /// 将源图像灰度化,并转化为8位灰度图像. /// </summary> ...

  2. C#图片灰度处理(位深度24→位深度8)、C#图片二值化处理(位深度8→位深度1)

    C#图片灰度处理(位深度24→位深度8) #region 灰度处理 /// <summary> /// 将源图像灰度化,并转化为8位灰度图像. /// </summary> / ...

  3. 图像转置的SSE优化(支持8位、24位、32位),提速4-6倍。

    一.前言 转置操作在很多算法上都有着广泛的应用,在数学上矩阵转置更有着特殊的意义.而在图像处理上,如果说图像数据本身的转置,除了显示外,本身并无特殊含义,但是在某些情况下,确能有效的提高算法效率,比如 ...

  4. SSE图像算法优化系列四:图像转置的SSE优化(支持8位、24位、32位),提速4-6倍

    一.前言 转置操作在很多算法上都有着广泛的应用,在数学上矩阵转置更有着特殊的意义.而在图像处理上,如果说图像数据本身的转置,除了显示外,本身并无特殊含义,但是在某些情况下,确能有效的提高算法效率,比如 ...

  5. MD5值转换(Hex 32位 <-> base64 24位)

    关于MD5值的原理本文不在介绍,本文主要介绍MD5值的两种编码的相互转换(32位和BASE64编码的24位),实际应用过程中经常会涉及到两种编码的相互转换.快熟使用工具tomeko.net. C#示例 ...

  6. C#保存图片到文件夹区分8位和24位

    1.保存图像--24位位图(显示的图像,包括增加结果到界面上的数据) Image image2 = default(Image); image2 = cogRecordDisplay1.CreateC ...

  7. 怎么把PNG图的位深度24位变成32位

    在PS里把图片的变成层模式,不透明度设置成99%,在保存成PNG

  8. 颜色模式中8位,16位,24位,32位色彩是什么意思?会有什么区别?计算机颜色格式( 8位 16位 24位 32位色)<转>

    颜色模式中8位,16位,24位,32位色彩是什么意思?会有什么区别简单地说这里说的位数和windows系统显示器设置中的颜色位数是一样的.表示的是能够显示出来的颜色的多少. 8位的意思是说,能够显示出 ...

  9. C# AES的128位、192位、256位加密

    C# AES的128位.192位.256位加密   AES加密原理,这里就不解释了,自行百度.这里主要细说AES的CBC加密模式下的128位.192位.256位加密区别,参考 对称加密和分组加密中的四 ...

随机推荐

  1. [WebGL入门]十三,minMatrix.js和坐标变换矩阵

    注:文章译自http://wgld.org/,原作者杉本雅広(doxas),文章中假设有我的额外说明,我会加上[lufy:],另外,鄙人webgl研究还不够深入,一些专业词语,假设翻译有误,欢迎大家指 ...

  2. html常用属性border-radius、linear-gradient怎么使用

    html常用属性border-radius.linear-gradient怎么使用 一.总结 一句话总结: 1.border-radius: 8px 8px 8px 8px !important; 2 ...

  3. 【hdu2222】【poj2945】AC自动机入门题

    HDU2222 传送门 题目分析 裸题:注意构建自动机用的是模式串,思想和kmp很类似. code: #include<iostream> #include<cstdio> # ...

  4. lucene 7.x 查询

    @Test public void indexSearch() throws IOException, ParseException { //Termquery:精确string查询 // Query ...

  5. Facebook巴特尔与谷歌移动广告 急于打开中国市场

    随着Facebook(62.5, -0.69, -1.09%)即将设立了销售办事处在北京发酵消息.谷歌(556.33, 2.43, 0.44%)似还差点自觉保护国内市场. 6月5日,谷歌在深圳举行了面 ...

  6. QT开发环境的建立以及QTE4.6.3、tslib1.4的移植过程

    1.首先是建立Linux开发环境1.1.在windowsXP下安装博创公司提供的虚拟机软件VMware Workstation,版本为VMware-workstation-full-7.0.1-227 ...

  7. Cocos2d-x3.1下实现相似iOS页面滑动指示圆点

    原文地址:http://blog.csdn.net/qqmcy/article/details/37612457 代码下载:http://download.csdn.net/detail/qqmcy/ ...

  8. Why I Choose Delphi Summary

    Over the summer, there has been a number of blog posts on this topic, but I haven't seen a complete ...

  9. Boltzmann 玻尔兹曼机(BM)

    Hopfield + 模拟退火 ⇒ Boltimann machine(随机神经网络),由 Hinton 和他的长期合作者 Sejnowski(Hopfield 的博士生) 共同提出. 1. 基本公式 ...

  10. 关于MySql链接url参数的设置 专题

    报错: Establishing SSL connection without server's identity verification is not recommended. According ...