RulerPainter.cs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  1. using PaintDotNet;
  2. using PaintDotNet.Base.CommTool;
  3. using PaintDotNet.Base.SettingModel;
  4. using PaintDotNet.DbOpreate.DbModel;
  5. using System;
  6. using System.Collections.Generic;
  7. using System.Drawing;
  8. using System.Drawing.Drawing2D;
  9. using System.Linq;
  10. using System.Text;
  11. using System.Threading.Tasks;
  12. namespace Metis.AutoAnalysis
  13. {
  14. class RulerPainter
  15. {
  16. public RulerModel rulerModel;//标尺样式信息
  17. public int lineLength = 1;//标尺长度
  18. public bool getLengthFromConfig = true;//是否从配置文件获取长度
  19. private double micronRatio = 1;
  20. //标志
  21. public mic_rulers xmlSaveModel;//存储标尺信息(xml或者预览拍摄选中标尺)
  22. /// <summary>
  23. /// 换算完的标尺信息,包含所有系统内得单位
  24. /// </summary>
  25. public Dictionary<MeasurementUnit, double> rules = new Dictionary<MeasurementUnit, double>();
  26. /// <summary>
  27. /// AxioVision标尺单位对应
  28. /// </summary>
  29. public Dictionary<int, MeasurementUnit> rule = new Dictionary<int, MeasurementUnit>() { { 76, MeasurementUnit.Micron }, { 75, MeasurementUnit.Millimeter }, { 74, MeasurementUnit.Centimeter }, { 77, MeasurementUnit.Nano }, { 81, MeasurementUnit.Inch }, { 84, MeasurementUnit.Mil } };
  30. public RulerPainter()
  31. {
  32. InitRulerInfo();
  33. }
  34. private void InitRulerInfo()
  35. {
  36. //Startup.instance.InitRulerInfo();
  37. this.rulerModel = Startup.instance.rulerModel;
  38. this.xmlSaveModel = Startup.instance.ruleDB;
  39. List<mic_rulers> mic_rulersAll = new List<mic_rulers>();
  40. if (this.xmlSaveModel == null && mic_rulersAll.Count > 0)
  41. this.xmlSaveModel = mic_rulersAll[0];
  42. this.rules.Clear();
  43. if (this.xmlSaveModel != null && this.xmlSaveModel.pixel_length != 0)
  44. {
  45. //计算单位长度 比如0.05英寸/像素; 100纳米/像素;
  46. double unitLength = (double)(this.xmlSaveModel.physical_length / (decimal)this.xmlSaveModel.pixel_length);
  47. switch (this.xmlSaveModel.ruler_units)
  48. {
  49. case (int)MeasurementUnit.Inch://英寸
  50. this.rules.Add(MeasurementUnit.Inch, unitLength); //英寸
  51. this.rules.Add(MeasurementUnit.Mil, 1000 * unitLength); //米尔
  52. this.rules.Add(MeasurementUnit.Centimeter, 2.54 * unitLength); //厘米
  53. this.rules.Add(MeasurementUnit.Millimeter, 25.4 * unitLength); //毫米
  54. this.rules.Add(MeasurementUnit.Micron, 25400 * unitLength); //微米
  55. this.rules.Add(MeasurementUnit.Nano, 25400000 * unitLength); //纳米
  56. break;
  57. case (int)MeasurementUnit.Mil://米尔
  58. this.rules.Add(MeasurementUnit.Inch, 0.001 * unitLength); //英寸
  59. this.rules.Add(MeasurementUnit.Mil, unitLength); //米尔
  60. this.rules.Add(MeasurementUnit.Centimeter, 0.00254 * unitLength); //厘米
  61. this.rules.Add(MeasurementUnit.Millimeter, 0.0254 * unitLength); //毫米
  62. this.rules.Add(MeasurementUnit.Micron, 25.4 * unitLength); //微米
  63. this.rules.Add(MeasurementUnit.Nano, 25400 * unitLength); //纳米
  64. break;
  65. case (int)MeasurementUnit.Centimeter://厘米
  66. this.rules.Add(MeasurementUnit.Inch, 0.3937008 * unitLength); //英寸
  67. this.rules.Add(MeasurementUnit.Mil, 393.7008 * unitLength); //米尔
  68. this.rules.Add(MeasurementUnit.Centimeter, unitLength); //厘米
  69. this.rules.Add(MeasurementUnit.Millimeter, 10 * unitLength); //毫米
  70. this.rules.Add(MeasurementUnit.Micron, 10000 * unitLength); //微米
  71. this.rules.Add(MeasurementUnit.Nano, 10000000 * unitLength); //纳米
  72. break;
  73. case (int)MeasurementUnit.Millimeter://毫米
  74. this.rules.Add(MeasurementUnit.Inch, 0.0393701 * unitLength); //英寸
  75. this.rules.Add(MeasurementUnit.Mil, 39.3701 * unitLength); //米尔
  76. this.rules.Add(MeasurementUnit.Centimeter, 0.1 * unitLength); //厘米
  77. this.rules.Add(MeasurementUnit.Millimeter, unitLength); //毫米
  78. this.rules.Add(MeasurementUnit.Micron, 1000 * unitLength); //微米
  79. this.rules.Add(MeasurementUnit.Nano, 1000000 * unitLength); //纳米
  80. break;
  81. case (int)MeasurementUnit.Micron://微米
  82. this.rules.Add(MeasurementUnit.Inch, 0.00003937007874 * unitLength); //英寸
  83. this.rules.Add(MeasurementUnit.Mil, 0.03937007874 * unitLength); //米尔
  84. this.rules.Add(MeasurementUnit.Centimeter, 0.0001 * unitLength); //厘米
  85. this.rules.Add(MeasurementUnit.Millimeter, 0.001 * unitLength); //毫米
  86. this.rules.Add(MeasurementUnit.Micron, unitLength); //微米
  87. this.rules.Add(MeasurementUnit.Nano, 1000 * unitLength); //纳米
  88. break;
  89. case (int)MeasurementUnit.Nano://纳米
  90. this.rules.Add(MeasurementUnit.Inch, 3.9370e-8 * unitLength); //英寸
  91. this.rules.Add(MeasurementUnit.Mil, 3.9370e-5 * unitLength); //米尔
  92. this.rules.Add(MeasurementUnit.Centimeter, 1e-7 * unitLength); //厘米
  93. this.rules.Add(MeasurementUnit.Millimeter, 1e-6 * unitLength); //毫米
  94. this.rules.Add(MeasurementUnit.Micron, 0.001 * unitLength); //微米
  95. this.rules.Add(MeasurementUnit.Nano, unitLength); //纳米
  96. break;
  97. default:
  98. this.xmlSaveModel = null;
  99. break;
  100. }
  101. }
  102. }
  103. public decimal Multiple
  104. {
  105. get
  106. {
  107. return this.xmlSaveModel.gain_multiple;
  108. }
  109. }
  110. public decimal RulerValue
  111. {
  112. get
  113. {
  114. return this.rulerModel.autoRulerValue;
  115. }
  116. }
  117. /// <summary>
  118. /// 每像素实际单位长度
  119. /// </summary>
  120. public double MicronRatioPerPixel
  121. {
  122. get
  123. {
  124. //config.xml中RulerId必须是数据库mic_ruler中已经存在的
  125. var gainNumber = this.xmlSaveModel.gain_multiple;//获取放大倍数
  126. if (getLengthFromConfig)//判断是否从配置文件获取长度
  127. {
  128. lineLength = Convert.ToInt32(this.rulerModel.autoRulerValue);//标尺长度 要除以放大倍数
  129. }
  130. Dictionary<MeasurementUnit, double> measurementUnitDictionary = this.rules;
  131. //以微米为基础单位
  132. double micron = measurementUnitDictionary[MeasurementUnit.Micron];//每像素多少微米长度
  133. double actualLineLength = (int)(lineLength / gainNumber);//除以放大倍数后的实际物理长度
  134. int pixelLength = Convert.ToInt32(actualLineLength / micron);//换算为像素长度
  135. //实际单位
  136. MeasurementUnit unit = MeasurementUnit.Micron;
  137. micronRatio = measurementUnitDictionary[unit];//每像素实际单位长度
  138. return micronRatio;
  139. }
  140. }
  141. public void DrawRuler(ref Bitmap bmp)
  142. {
  143. if (this.xmlSaveModel == null)
  144. return;//不能获得放大倍数
  145. //config.xml中RulerId必须是数据库mic_ruler中已经存在的
  146. var gainNumber = this.xmlSaveModel.gain_multiple;//获取放大倍数
  147. if (getLengthFromConfig)//判断是否从配置文件获取长度
  148. {
  149. lineLength = Convert.ToInt32(this.rulerModel.autoRulerValue);//标尺长度 要除以放大倍数
  150. }
  151. Dictionary<MeasurementUnit, double> measurementUnitDictionary = this.rules;
  152. //以微米为基础单位
  153. double micron = measurementUnitDictionary[MeasurementUnit.Micron];//每像素多少微米长度
  154. double actualLineLength = (int)(lineLength / gainNumber);//除以放大倍数后的实际物理长度
  155. int pixelLength = Convert.ToInt32(actualLineLength / micron);//换算为像素长度
  156. //实际单位
  157. MeasurementUnit unit = MeasurementUnit.Micron;
  158. micronRatio = measurementUnitDictionary[unit];//每像素实际单位长度
  159. string unitAbbreviation = "µm";
  160. SizeF windowSize = bmp.Size;//窗体尺寸
  161. //线样式
  162. Pen linePen = new Pen(Color.FromArgb(this.rulerModel.lineColor));
  163. linePen.Width = (int)this.rulerModel.lineWidth;
  164. //边框样式
  165. Pen borderPen = new Pen(Color.FromArgb(this.rulerModel.borderColor));
  166. borderPen.Width = (int)this.rulerModel.borderWidth;
  167. int lineWidthOffset = (int)this.rulerModel.lineWidth / 2 - 1;
  168. int offset = borderPen.Width > 0 ? (int)(borderPen.Width / 2) - 2 : 0;
  169. //背景大小
  170. decimal backLength = pixelLength * this.rulerModel.backgroundSize / 100;
  171. //垂线
  172. decimal verticalLength = pixelLength * this.rulerModel.verticalLineLength / 100;
  173. //文字
  174. string text = actualLineLength + unitAbbreviation;
  175. //string text = Math.Round(actualLineLength, MeasureDrawObject.decimalPlaces).ToString() + unitAbbreviation;//小数保留
  176. decimal textHeight = pixelLength * this.rulerModel.textHeight / 100;
  177. Font textFont = new Font(this.rulerModel.textFont, (float)this.rulerModel.textFontSize);
  178. int fontNewHeight = lineWidthOffset + (int)(textHeight + new Decimal(textFont.Height));
  179. int abc = fontNewHeight > ((int)verticalLength / 2 - 2) ? fontNewHeight : ((int)verticalLength / 2 - 2);
  180. //标尺最终尺寸
  181. int rulerWidth = pixelLength + (int)(backLength * 2) + (int)(linePen.Width * 2) + offset * 2;
  182. int rulerHeight = (int)verticalLength / 2 + abc + (int)(backLength * 2) + lineWidthOffset + 2 + offset * 2;
  183. int rulerPosition = this.rulerModel.rulerPosition;//标尺位置
  184. decimal rulerMargin = this.rulerModel.rulerMargin / 100;//标尺边距
  185. float marginLR = (float)rulerMargin * windowSize.Width;//左右边距
  186. float marginTB = (float)rulerMargin * windowSize.Height;//上下边距
  187. float offsetBorder = borderPen.Width > 0 ? borderPen.Width / 2 : 0;
  188. PointF startPoint = new PointF();
  189. switch (rulerPosition)
  190. {
  191. case 1://左上
  192. startPoint.X = rulerWidth / 2f - lineWidthOffset + offsetBorder + marginLR;
  193. startPoint.Y = fontNewHeight + (float)backLength - lineWidthOffset + offsetBorder + marginTB;
  194. break;
  195. case 2://右上
  196. startPoint.X = windowSize.Width - (rulerWidth / 2f - lineWidthOffset + offsetBorder) - marginLR;
  197. startPoint.Y = fontNewHeight + (float)backLength - lineWidthOffset + offsetBorder + marginTB;
  198. break;
  199. case 3://左下
  200. startPoint.X = rulerWidth / 2f - lineWidthOffset + offsetBorder + marginLR;
  201. startPoint.Y = windowSize.Height - (rulerHeight - (fontNewHeight + (float)backLength)) - offsetBorder - marginTB;
  202. break;
  203. case 4://右下
  204. startPoint.X = windowSize.Width - (rulerWidth / 2f - lineWidthOffset + offsetBorder) - marginLR;
  205. startPoint.Y = windowSize.Height - (rulerHeight - (fontNewHeight + (float)backLength)) - offsetBorder - marginTB;
  206. break;
  207. }
  208. Graphics g = Graphics.FromImage((Image)bmp);
  209. g.SmoothingMode = SmoothingMode.AntiAlias;
  210. RectangleF rectangle = new Rectangle();
  211. DrawRulerHelper.drawRuler(this.rulerModel, g, startPoint, pixelLength, text, out rectangle);
  212. g.Dispose();
  213. }
  214. }
  215. }