BSEImgFileMgr.cs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374
  1. 
  2. using OTSCLRINTERFACE;
  3. using OTSDataType;
  4. using System;
  5. using System.Collections.Generic;
  6. using System.Drawing;
  7. using System.IO;
  8. using System.Linq;
  9. using System.Runtime.InteropServices;
  10. using System.Text;
  11. using System.Threading.Tasks;
  12. using System.Windows;
  13. using System.Windows.Forms;
  14. namespace OTSModelSharp
  15. {
  16. public class CBSEImageFileMgr
  17. {
  18. [StructLayout(LayoutKind.Sequential, Pack = 1)]
  19. public struct BITMAPFILEHEADER
  20. {
  21. public UInt16 bfType;
  22. public UInt32 bfSize;
  23. public UInt16 bfReserved1;
  24. public UInt16 bfReserved2;
  25. public UInt32 bfOffBits;
  26. };
  27. [StructLayout(LayoutKind.Sequential, Pack = 1)]
  28. public struct BITMAPINFOHEADER
  29. {
  30. public UInt32 biSize;
  31. public UInt32 biWidth;
  32. public UInt32 biHeight;
  33. public UInt16 biPlanes;
  34. public UInt16 biBitCount;
  35. public UInt16 biCompression;
  36. public UInt32 biSizeImage;
  37. public UInt32 biXPelsPerMeter;
  38. public UInt32 biYPelsPerMeter;
  39. public UInt32 biClrUsed;
  40. public UInt32 biClrImportant;
  41. };
  42. [StructLayout(LayoutKind.Sequential, Pack = 1)]
  43. public struct RGBQUAD
  44. {
  45. public Byte rgbBlue;
  46. public Byte rgbGreen;
  47. public Byte rgbRed;
  48. public Byte rgbReserved;
  49. public Byte pColorTables;
  50. };
  51. // RGBQUAD[] pColorTable;
  52. // BSE image
  53. CBSEImgClr m_poBSE ;
  54. public String BMP_IMG_FILE_EXT = ".bmp";
  55. //System.Drawing.Size rect = new System.Drawing.Size();
  56. public String BSE_IMG_FILE_FILTER = "BSE image Files (*.img)|*.img||";
  57. // BSE image
  58. public String BSE_IMG_FILE_EXT = ".img";
  59. // file pathname
  60. String m_strPathName;
  61. public void CBSEImgFileMgr()
  62. {
  63. // initialization
  64. Init();
  65. }
  66. // initialization
  67. public void Init()
  68. {
  69. // initialization
  70. //m_poBSE = new CBSEImg();
  71. }
  72. // Load/Save
  73. public bool Load(String a_strPathName /*= _T("")*/, bool a_bClear /*= TRUE*/)
  74. {
  75. // AFX_MANAGE_STATE(AfxGetStaticModuleState());
  76. // clear all data if necessary
  77. if (a_bClear)
  78. {
  79. Init();
  80. }
  81. // check file pathname
  82. a_strPathName.Trim();
  83. if (a_strPathName == "")
  84. {
  85. // file open dialog
  86. OpenFileDialog openFileDialog = new OpenFileDialog();
  87. if (openFileDialog.ShowDialog() != DialogResult.OK)
  88. {
  89. return false;
  90. }
  91. // get file pathname
  92. openFileDialog.Filter = BSE_IMG_FILE_FILTER;
  93. a_strPathName = openFileDialog.FileName;
  94. }
  95. // open the particle analysis standard file
  96. if (!File.Exists(a_strPathName))
  97. {
  98. // failed to open the file
  99. return false;
  100. }
  101. FileStream NewText = File.Create(a_strPathName);
  102. NewText.Close();
  103. // file pathname
  104. m_strPathName = a_strPathName;
  105. // ok, return TRUE
  106. return true;
  107. }
  108. public bool LoadFromBitmap(String a_strPathName /*= _T("")*/, bool a_bClear/* = TRUE*/)
  109. {
  110. // AFX_MANAGE_STATE(AfxGetStaticModuleState());
  111. // prepare file
  112. if (a_bClear)
  113. {
  114. Init();
  115. }
  116. // check file pathname
  117. a_strPathName.Trim();
  118. if (a_strPathName == "")
  119. {
  120. // file open dialog
  121. OpenFileDialog openFileDialog = new OpenFileDialog();
  122. if (openFileDialog.ShowDialog() != DialogResult.OK)
  123. {
  124. return false;
  125. }
  126. // get file pathname
  127. openFileDialog.Filter = BSE_IMG_FILE_FILTER;
  128. a_strPathName = openFileDialog.FileName;
  129. }
  130. else
  131. {
  132. m_strPathName = a_strPathName;
  133. }
  134. Byte[] pPixel ;
  135. Byte[] pBmInfo;
  136. BITMAPFILEHEADER pBmfh;
  137. pBmfh = new BITMAPFILEHEADER();
  138. OpenFileDialog openFileDialogs = new OpenFileDialog();
  139. if (openFileDialogs.ShowDialog() != DialogResult.OK)
  140. {
  141. return false;
  142. }
  143. // read file header
  144. pBmInfo = new Byte[pBmfh.bfOffBits - 14];
  145. FileStream aFile = new FileStream(pBmfh.ToString(), FileMode.Open);
  146. aFile.Read(pBmInfo, 0, 200);
  147. BITMAPINFOHEADER bmih = new BITMAPINFOHEADER();
  148. File.Copy(bmih.ToString(), pBmInfo.ToString());
  149. long width = bmih.biWidth;//获取宽度
  150. int bitCount = bmih.biBitCount;//获取位数
  151. long height = bmih.biHeight;//获取高度
  152. long LineBytes = (width * bitCount + 31) / 32 * 4;//计算每行像素所占的字节数
  153. pPixel = new Byte[height * LineBytes];
  154. aFile.Read(pPixel, 0, (int)height * (int)LineBytes);
  155. aFile.Close();
  156. System.Drawing.Rectangle images = new System.Drawing.Rectangle(0, 0, (int)width - 0, 0 - (int)height);
  157. m_poBSE.SetImageRect(images);
  158. m_poBSE.InitImageData(images.Width, images.Height);
  159. Byte[] pImageData = m_poBSE.GetImageDataPtr();
  160. long nActImageSize = width * height;
  161. for (int i = 0; i < height; i++)
  162. {
  163. File.Copy(pImageData.ToString() + i * width, pPixel.ToString() + (height - 1 - i) * width);
  164. }
  165. File.Delete(pPixel.ToString());
  166. File.Delete(pBmInfo.ToString());
  167. File.Delete(pBmfh.ToString());
  168. return true;
  169. }
  170. public bool SaveIntoBitmap(String a_strPathName)
  171. {
  172. // check file pathname
  173. a_strPathName.Trim();
  174. if (a_strPathName == "")
  175. {
  176. // file open dialog
  177. OpenFileDialog openFileDialog = new OpenFileDialog();
  178. if (openFileDialog.ShowDialog() != DialogResult.OK)
  179. {
  180. return false;
  181. }
  182. // get file pathname
  183. openFileDialog.Filter = BSE_IMG_FILE_FILTER;
  184. a_strPathName = openFileDialog.FileName;
  185. }
  186. Bitmap rstBm = CreateBitmap(m_poBSE.GetImageDataPtr(), m_poBSE.GetWidth(), m_poBSE.GetHeight());
  187. if (rstBm == null)
  188. {
  189. return false;
  190. }
  191. rstBm.Save(a_strPathName);
  192. return true;
  193. }
  194. byte[] StructureToByteArray(object obj)
  195. {
  196. int len = Marshal.SizeOf(obj);
  197. byte[] arr = new byte[len];
  198. IntPtr ptr = Marshal.AllocHGlobal(len);
  199. Marshal.StructureToPtr(obj, ptr, true);
  200. Marshal.Copy(ptr, arr, 0, len);
  201. Marshal.FreeHGlobal(ptr);
  202. return arr;
  203. }
  204. /// <summary>
  205. /// 使用byte[]数据,生成256色灰度 BMP 位图
  206. /// </summary>
  207. /// <param name="originalImageData"></param>
  208. /// <param name="originalWidth"></param>
  209. /// <param name="originalHeight"></param>
  210. /// <returns></returns>
  211. public static Bitmap CreateBitmap(byte[] originalImageData, int originalWidth, int originalHeight)
  212. {
  213. if (originalImageData == null || originalWidth == 0 || originalHeight == 0)
  214. {
  215. return null;
  216. }
  217. //指定8位格式,即256色
  218. Bitmap resultBitmap = new Bitmap(originalWidth, originalHeight, System.Drawing.Imaging.PixelFormat.Format8bppIndexed);
  219. //将该位图存入内存中
  220. MemoryStream curImageStream = new MemoryStream();
  221. resultBitmap.Save(curImageStream, System.Drawing.Imaging.ImageFormat.Bmp);
  222. curImageStream.Flush();
  223. //由于位图数据需要DWORD对齐(4byte倍数),计算需要补位的个数
  224. int curPadNum = ((originalWidth * 8 + 31) / 32 * 4) - originalWidth;
  225. //最终生成的位图数据大小
  226. int bitmapDataSize = ((originalWidth * 8 + 31) / 32 * 4) * originalHeight;
  227. //数据部分相对文件开始偏移,具体可以参考位图文件格式
  228. int dataOffset = ReadData(curImageStream, 10, 4);
  229. //改变调色板,因为默认的调色板是32位彩色的,需要修改为256色的调色板
  230. int paletteStart = 54;
  231. int paletteEnd = dataOffset;
  232. int color = 0;
  233. for (int i = paletteStart; i < paletteEnd; i += 4)
  234. {
  235. byte[] tempColor = new byte[4];
  236. tempColor[0] = (byte)color;
  237. tempColor[1] = (byte)color;
  238. tempColor[2] = (byte)color;
  239. tempColor[3] = (byte)0;
  240. color++;
  241. curImageStream.Position = i;
  242. curImageStream.Write(tempColor, 0, 4);
  243. }
  244. //最终生成的位图数据,以及大小,高度没有变,宽度需要调整
  245. byte[] destImageData = new byte[bitmapDataSize];
  246. int destWidth = originalWidth + curPadNum;
  247. //生成最终的位图数据,注意的是,位图数据 从左到右,从下到上,所以需要颠倒
  248. for (int originalRowIndex = originalHeight - 1; originalRowIndex >= 0; originalRowIndex--)
  249. {
  250. int destRowIndex = originalHeight - originalRowIndex - 1;
  251. for (int dataIndex = 0; dataIndex < originalWidth; dataIndex++)
  252. {
  253. //同时还要注意,新的位图数据的宽度已经变化destWidth,否则会产生错位
  254. destImageData[destRowIndex * destWidth + dataIndex] = originalImageData[originalRowIndex * originalWidth + dataIndex];
  255. }
  256. }
  257. //将流的Position移到数据段
  258. curImageStream.Position = dataOffset;
  259. //将新位图数据写入内存中
  260. curImageStream.Write(destImageData, 0, bitmapDataSize);
  261. curImageStream.Flush();
  262. //将内存中的位图写入Bitmap对象
  263. resultBitmap = new Bitmap(curImageStream);
  264. return resultBitmap;
  265. }
  266. /// <summary>
  267. /// 从内存流中指定位置,读取数据
  268. /// </summary>
  269. /// <param name="curStream"></param>
  270. /// <param name="startPosition"></param>
  271. /// <param name="length"></param>
  272. /// <returns></returns>
  273. public static int ReadData(MemoryStream curStream, int startPosition, int length)
  274. {
  275. int result = -1;
  276. byte[] tempData = new byte[length];
  277. curStream.Position = startPosition;
  278. curStream.Read(tempData, 0, length);
  279. result = BitConverter.ToInt32(tempData, 0);
  280. return result;
  281. }
  282. /// <summary>
  283. /// 向内存流中指定位置,写入数据
  284. /// </summary>
  285. /// <param name="curStream"></param>
  286. /// <param name="startPosition"></param>
  287. /// <param name="length"></param>
  288. /// <param name="value"></param>
  289. public static void WriteData(MemoryStream curStream, int startPosition, int length, int value)
  290. {
  291. curStream.Position = startPosition;
  292. curStream.Write(BitConverter.GetBytes(value), 0, length);
  293. }
  294. // file pathname
  295. public String GetPathName()
  296. {
  297. return m_strPathName;
  298. }
  299. public void SetPathName(String a_strPathName)
  300. {
  301. m_strPathName = a_strPathName;
  302. }
  303. //image
  304. public CBSEImgClr GetBSEImg()
  305. {
  306. return m_poBSE;
  307. }
  308. public void SetBSEImg(CBSEImgClr a_poBSE)
  309. {
  310. m_poBSE = a_poBSE;
  311. }
  312. }
  313. }