BitmapBlack.cs 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. using System;
  2. using System.Drawing;
  3. using System.Drawing.Imaging;
  4. using System.Runtime.InteropServices;
  5. namespace HNWD.Pregrant.Common
  6. {
  7. public class BitmapBlack
  8. {
  9. public static bool bSuccessed = true;
  10. public static Bitmap BitmapToBlack(Bitmap img, Double hsb)
  11. {
  12. int w = img.Width;
  13. int h = img.Height;
  14. Bitmap bmp = new Bitmap(w, h, PixelFormat.Format1bppIndexed);
  15. BitmapData data = bmp.LockBits(new Rectangle(0, 0, w, h), ImageLockMode.ReadWrite, PixelFormat.Format1bppIndexed);//将 Bitmap 锁定到系统内存中
  16. for (int y = 0; y < h; y++)
  17. {
  18. byte[] scan = new byte[(w + 7) / 8];
  19. for (int x = 0; x < w; x++)
  20. {
  21. Color c = img.GetPixel(x, y);
  22. if (c.GetBrightness() >= hsb)
  23. scan[x / 8] |= (byte)(0x80 >> (x % 8));//亮度值和原来比较,二值化处理
  24. }
  25. Marshal.Copy(scan, 0, (IntPtr)((int)data.Scan0 + data.Stride * y), scan.Length);
  26. }
  27. bmp.UnlockBits(data);//将 Bitmap 锁定到系统内存中
  28. return bmp;
  29. }
  30. //图片二值化
  31. public static Bitmap binarization(Bitmap img)
  32. {
  33. bSuccessed = true;
  34. int width = img.Width;
  35. int height = img.Height;
  36. int area = width * height;
  37. int[,] gray = new int[width, height];
  38. int average = 0;// 灰度平均值
  39. int graysum = 0;
  40. int graymean = 0;
  41. int grayfrontmean = 0;
  42. int graybackmean = 0;
  43. int pixelGray;
  44. int front = 0;
  45. int back = 0;
  46. int[] pix = new int[width * height];
  47. for (int i = 1; i < width; i++)
  48. { // 不算边界行和列,为避免越界
  49. for (int j = 1; j < height; j++)
  50. {
  51. pix[j * width + i] = img.GetPixel(i, j).ToArgb(); //得到单点上的颜色值
  52. int x = j * width + i;
  53. int r = (pix[x] >> 16) & 0xff;
  54. int g = (pix[x] >> 8) & 0xff;
  55. int b = pix[x] & 0xff;
  56. pixelGray = (int)(0.3 * r + 0.59 * g + 0.11 * b);// 计算每个坐标点的灰度
  57. gray[i, j] = (pixelGray << 16) + (pixelGray << 8) + (pixelGray);
  58. graysum += pixelGray;
  59. }
  60. }
  61. graymean = (int)(graysum / area);// 整个图的灰度平均值
  62. average = graymean;
  63. for (int i = 0; i < width; i++) // 计算整个图的二值化阈值
  64. {
  65. for (int j = 0; j < height; j++)
  66. {
  67. if (((gray[i, j]) & (0x0000ff)) < graymean)
  68. {
  69. graybackmean += ((gray[i, j]) & (0x0000ff));
  70. back++;
  71. }
  72. else
  73. {
  74. grayfrontmean += ((gray[i, j]) & (0x0000ff));
  75. front++;
  76. }
  77. }
  78. }
  79. if (front == 0 || back == 0)
  80. {
  81. bSuccessed = false;
  82. return null;
  83. }
  84. int frontvalue = (int)(grayfrontmean / front);// 前景中心
  85. int backvalue = (int)(graybackmean / back);// 背景中心
  86. float[] G = new float[frontvalue - backvalue + 1];// 方差数组
  87. int s = 0;
  88. for (int i1 = backvalue; i1 < frontvalue + 1; i1++)// 以前景中心和背景中心为区间采用大津法算法(OTSU算法)
  89. {
  90. back = 0;
  91. front = 0;
  92. grayfrontmean = 0;
  93. graybackmean = 0;
  94. for (int i = 0; i < width; i++)
  95. {
  96. for (int j = 0; j < height; j++)
  97. {
  98. if (((gray[i, j]) & (0x0000ff)) < (i1 + 1))
  99. {
  100. graybackmean += ((gray[i, j]) & (0x0000ff));
  101. back++;
  102. }
  103. else
  104. {
  105. grayfrontmean += ((gray[i, j]) & (0x0000ff));
  106. front++;
  107. }
  108. }
  109. }
  110. if (front == 0 || back == 0)
  111. {
  112. bSuccessed = false;
  113. return null;
  114. }
  115. grayfrontmean = (int)(grayfrontmean / front);
  116. graybackmean = (int)(graybackmean / back);
  117. G[s] = (((float)back / area) * (graybackmean - average)
  118. * (graybackmean - average) + ((float)front / area)
  119. * (grayfrontmean - average) * (grayfrontmean - average));
  120. s++;
  121. }
  122. float max = G[0];
  123. int index = 0;
  124. for (int i = 1; i < frontvalue - backvalue + 1; i++)
  125. {
  126. if (max < G[i])
  127. {
  128. max = G[i];
  129. index = i;
  130. }
  131. }
  132. for (int i = 0; i < width; i++)
  133. {
  134. for (int j = 0; j < height; j++)
  135. {
  136. int inin = j * width + i;
  137. if (((gray[i, j]) & (0x0000ff)) < (index + backvalue))
  138. {
  139. pix[inin] = Color.FromArgb(0, 0, 0).ToArgb();
  140. }
  141. else
  142. {
  143. pix[inin] = Color.FromArgb(255, 255, 255).ToArgb();
  144. }
  145. }
  146. }
  147. Bitmap temp = new Bitmap(width, height, System.Drawing.Imaging.PixelFormat.Format16bppRgb555);
  148. for (int i = 1; i < width; i++)
  149. { // 不算边界行和列,为避免越界
  150. for (int j = 1; j < height; j++)
  151. {
  152. img.SetPixel(i, j, Color.FromArgb(pix[j * width + i]));
  153. }
  154. }
  155. return temp;
  156. }
  157. /// <summary>
  158. /// 防锯齿
  159. /// </summary>
  160. /// <param name="uAction"></param>
  161. /// <param name="uParam"></param>
  162. /// <param name="lpvParam"></param>
  163. /// <param name="fuWinIni"></param>
  164. /// <returns></returns>
  165. [DllImport("user32.dll", EntryPoint = "SystemParametersInfo")]
  166. private static extern int SystemParametersInfo(int uAction,
  167. int uParam,
  168. string lpvParam,
  169. int fuWinIni
  170. );
  171. private static int BitmapHandlerAction = 75;//启用 或 关闭 平滑效果
  172. /// <summary>
  173. /// 关闭 平滑效果
  174. /// </summary>
  175. /// <returns></returns>
  176. public static int SetBitmapSmoothDisable()
  177. {
  178. return SystemParametersInfo(BitmapHandlerAction, 0, null, 0); //关闭 平滑效果
  179. }
  180. /// <summary>
  181. /// 启用 平滑效果
  182. /// </summary>
  183. /// <returns></returns>
  184. public static int SetBitmapSmoothEnable()
  185. {
  186. return SystemParametersInfo(BitmapHandlerAction, 1, null, 0); //关闭 平滑效果
  187. }
  188. }
  189. }