BitmapHelper.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. using AI.Common;
  2. using System;
  3. using System.Drawing;
  4. using System.Drawing.Imaging;
  5. using System.IO;
  6. using System.Runtime.InteropServices;
  7. using System.Windows.Media.Imaging;
  8. using Rectangle = System.Drawing.Rectangle;
  9. namespace AIDiagnosisDemo.Infrastucture
  10. {
  11. internal class BitmapHelper
  12. {
  13. public static byte[] BitmapToBytes(Bitmap bitmap)
  14. {
  15. if (bitmap == null)
  16. {
  17. return null;
  18. }
  19. using (var stream = new MemoryStream())
  20. {
  21. bitmap.Save(stream, ImageFormat.Bmp);
  22. var buffer = new byte[stream.Length];
  23. stream.Position = 0;
  24. stream.Read(buffer, 0, buffer.Length);
  25. return buffer;
  26. }
  27. }
  28. public static BitmapImage BitmapToBitmapImage(Bitmap bitmap)
  29. {
  30. BitmapImage bmpimg = new BitmapImage();
  31. using (MemoryStream ms = new MemoryStream())
  32. {
  33. bitmap.Save(ms, ImageFormat.Png);
  34. bmpimg.BeginInit();
  35. bmpimg.StreamSource = ms;
  36. bmpimg.CacheOption = BitmapCacheOption.OnLoad;
  37. bmpimg.EndInit();
  38. bmpimg.Freeze();
  39. ms.Dispose();
  40. }
  41. return bmpimg;
  42. }
  43. public static RawImage BitmapToRawImage(Bitmap image, bool keepColorType = false)
  44. {
  45. int width = image.Width;
  46. int height = image.Height;
  47. PixelFormat pixelFormat = image.PixelFormat;
  48. if (pixelFormat != PixelFormat.Format24bppRgb && pixelFormat != PixelFormat.Format32bppArgb
  49. && pixelFormat != PixelFormat.Format8bppIndexed && pixelFormat != PixelFormat.Format16bppGrayScale)
  50. {
  51. throw new Exception("Unexpected image pixel format:" + pixelFormat);
  52. }
  53. EnumColorType origColorType = EnumColorType.Gray8;
  54. int origBytesPerPixel = 1;
  55. if (pixelFormat == PixelFormat.Format8bppIndexed)
  56. {
  57. origColorType = EnumColorType.Gray8;
  58. origBytesPerPixel = 1;
  59. }
  60. else if (pixelFormat == PixelFormat.Format16bppGrayScale)
  61. {
  62. origColorType = EnumColorType.Gray16;
  63. origBytesPerPixel = 2;
  64. }
  65. else if (pixelFormat == PixelFormat.Format24bppRgb)
  66. {
  67. // 注意Bitmap里的24bppRgb其实通道顺序是BGR
  68. origColorType = EnumColorType.Bgr;
  69. origBytesPerPixel = 3;
  70. }
  71. else
  72. {
  73. // 注意Bitmap里的32Argb其实通道顺序是Bgra
  74. origColorType = EnumColorType.Bgra;
  75. origBytesPerPixel = 4;
  76. }
  77. EnumColorType dstColorType;
  78. int dstBytesPerPixel;
  79. if (keepColorType)
  80. {
  81. dstColorType = origColorType;
  82. dstBytesPerPixel = origBytesPerPixel;
  83. }
  84. else
  85. {
  86. // 如果没有指定要keepColorType的话,默认都转成BGR
  87. dstColorType = EnumColorType.Bgr;
  88. dstBytesPerPixel = 3;
  89. }
  90. var bmData = image.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadOnly, pixelFormat);
  91. byte[] dstDataArray = new byte[width * height * dstBytesPerPixel];
  92. unsafe
  93. {
  94. int stride = bmData.Stride;
  95. int dstStride = width * dstBytesPerPixel;
  96. IntPtr ptr = bmData.Scan0;
  97. IntPtr ptrH, ptrW;
  98. // 原图和目标图的ColorType相同
  99. if (origColorType == dstColorType)
  100. {
  101. for (int nh = 0; nh < height; nh++)
  102. {
  103. ptrH = IntPtr.Add(ptr, nh * stride);
  104. Marshal.Copy(ptrH, dstDataArray, nh * dstStride, dstStride);
  105. }
  106. }
  107. // 原图和目标图的ColorType不同
  108. else
  109. {
  110. // 如果原图是8位灰度图
  111. if (origColorType == EnumColorType.Gray8)
  112. {
  113. if (dstColorType == EnumColorType.Gray16)
  114. {
  115. byte gray;
  116. int dstOffset;
  117. for (int nh = 0; nh < height; nh++)
  118. {
  119. ptrH = IntPtr.Add(ptr, nh * stride);
  120. for (int nw = 0; nw < width; nw++)
  121. {
  122. ptrW = IntPtr.Add(ptrH, nw * origBytesPerPixel);
  123. gray = Marshal.ReadByte(ptrW);
  124. dstOffset = nh * dstStride + nw * dstBytesPerPixel;
  125. dstDataArray[dstOffset] = gray;
  126. // 高位为0,因此不用赋值
  127. }
  128. }
  129. }
  130. else
  131. {
  132. byte gray;
  133. int dstOffset;
  134. for (int nh = 0; nh < height; nh++)
  135. {
  136. ptrH = IntPtr.Add(ptr, nh * stride);
  137. for (int nw = 0; nw < width; nw++)
  138. {
  139. ptrW = IntPtr.Add(ptrH, nw * origBytesPerPixel);
  140. gray = Marshal.ReadByte(ptrW);
  141. dstOffset = nh * dstStride + nw * dstBytesPerPixel;
  142. dstDataArray[dstOffset] = gray;
  143. dstDataArray[dstOffset + 1] = gray;
  144. dstDataArray[dstOffset + 2] = gray;
  145. }
  146. }
  147. if (dstColorType == EnumColorType.Bgra)
  148. {
  149. for (int nh = 0; nh < height; nh++)
  150. {
  151. for (int nw = 0; nw < width; nw++)
  152. {
  153. dstOffset = nh * dstStride + nw * dstBytesPerPixel;
  154. dstDataArray[dstOffset + 3] = 255;
  155. }
  156. }
  157. }
  158. }
  159. }
  160. // 如果原图是BGR彩色图
  161. if (origColorType == EnumColorType.Bgr)
  162. {
  163. if (dstColorType == EnumColorType.Gray8 || dstColorType == EnumColorType.Gray16)
  164. {
  165. byte red, green, blue, gray;
  166. int dstOffset;
  167. for (int nh = 0; nh < height; nh++)
  168. {
  169. ptrH = IntPtr.Add(ptr, nh * stride);
  170. for (int nw = 0; nw < width; nw++)
  171. {
  172. ptrW = IntPtr.Add(ptrH, nw * origBytesPerPixel);
  173. blue = Marshal.ReadByte(ptrW);
  174. ptrW = IntPtr.Add(ptrW, 1);
  175. green = Marshal.ReadByte(ptrW);
  176. ptrW = IntPtr.Add(ptrW, 1);
  177. red = Marshal.ReadByte(ptrW);
  178. gray = RawImage.PixelRGBToGray(red, green, blue);
  179. dstOffset = nh * dstStride + nw * dstBytesPerPixel;
  180. dstDataArray[dstOffset] = gray;
  181. }
  182. }
  183. }
  184. if (dstColorType == EnumColorType.Bgra)
  185. {
  186. int dstOffset;
  187. for (int nh = 0; nh < height; nh++)
  188. {
  189. ptrH = IntPtr.Add(ptr, nh * stride);
  190. for (int nw = 0; nw < width; nw++)
  191. {
  192. ptrW = IntPtr.Add(ptrH, nw * origBytesPerPixel);
  193. dstOffset = nh * dstStride + nw * dstBytesPerPixel;
  194. Marshal.Copy(ptrW, dstDataArray, dstOffset, 3);
  195. dstDataArray[dstOffset + 3] = 255;
  196. }
  197. }
  198. }
  199. }
  200. // 如果原图是BGRA彩色图
  201. if (origColorType == EnumColorType.Bgra)
  202. {
  203. if (dstColorType == EnumColorType.Gray8 || dstColorType == EnumColorType.Gray16)
  204. {
  205. byte red, green, blue, gray;
  206. int dstOffset;
  207. for (int nh = 0; nh < height; nh++)
  208. {
  209. ptrH = IntPtr.Add(ptr, nh * stride);
  210. for (int nw = 0; nw < width; nw++)
  211. {
  212. ptrW = IntPtr.Add(ptrH, nw * origBytesPerPixel);
  213. blue = Marshal.ReadByte(ptrW);
  214. ptrW = IntPtr.Add(ptrW, 1);
  215. green = Marshal.ReadByte(ptrW);
  216. ptrW = IntPtr.Add(ptrW, 1);
  217. red = Marshal.ReadByte(ptrW);
  218. gray = RawImage.PixelRGBToGray(red, green, blue);
  219. dstOffset = nh * dstStride + nw * dstBytesPerPixel;
  220. dstDataArray[dstOffset] = gray;
  221. }
  222. }
  223. }
  224. if (dstColorType == EnumColorType.Bgr)
  225. {
  226. int dstOffset;
  227. for (int nh = 0; nh < height; nh++)
  228. {
  229. ptrH = IntPtr.Add(ptr, nh * stride);
  230. for (int nw = 0; nw < width; nw++)
  231. {
  232. ptrW = IntPtr.Add(ptrH, nw * origBytesPerPixel);
  233. dstOffset = nh * dstStride + nw * dstBytesPerPixel;
  234. Marshal.Copy(ptrW, dstDataArray, dstOffset, 3);
  235. }
  236. }
  237. }
  238. }
  239. }
  240. }
  241. image.UnlockBits(bmData);
  242. return new RawImage(dstDataArray, width, height, dstColorType);
  243. }
  244. }
  245. }