PicExControl.cs 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839
  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel;
  4. using System.Drawing;
  5. using System.Data;
  6. using System.Linq;
  7. using System.Text;
  8. using System.Threading.Tasks;
  9. using System.Windows.Forms;
  10. using System.Drawing.Drawing2D;
  11. namespace SIASUN.Autopilot.View
  12. {
  13. public partial class PicExControl : UserControl
  14. {
  15. /// <summary>
  16. /// 支持缩放和画框以及对框进行微调的图片显示控件
  17. /// </summary>
  18. public PicExControl()
  19. {
  20. //InitializeComponent();
  21. _fineTuningRect = new FineTuningRect { FatherControl = this };
  22. SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer, true);
  23. }
  24. #region 字段和事件
  25. public delegate void MouseWheelDraw(object sender, MouseEventArgs e); //显示树
  26. public event MouseWheelDraw MouseWheelDrawEvent;
  27. public delegate void AfterDraw(bool isMove, bool isRight);
  28. public event AfterDraw AfterDrawEvent;
  29. /// <summary>
  30. /// 鼠标移动显示坐标
  31. /// </summary>
  32. /// <param name="e"></param>
  33. public delegate void MouseMoveTooltip(MouseEventArgs e); //鼠标移动显示坐标
  34. /// <summary>
  35. /// 鼠标移动显示坐标
  36. /// </summary>
  37. public event MouseMoveTooltip MouseMoveTooltipEvent;
  38. /// <summary>
  39. /// 画路径
  40. /// </summary>
  41. /// <param name="g"></param>
  42. public delegate void DrawPath(Graphics g); //画路径
  43. /// <summary>
  44. /// 画原始路径
  45. /// </summary>
  46. public event DrawPath DrawOriginalPathEvent; //画原始路径
  47. /// <summary>
  48. /// 画行驶路径
  49. /// </summary>
  50. public event DrawPath DrawDrivingPathEvent; //画行驶路径
  51. /// <summary>
  52. /// 原图
  53. /// </summary>
  54. private Image _image; //原图
  55. private FineTuningRect _fineTuningRect;
  56. /// <summary>
  57. /// 鼠标所在矩形位置
  58. /// </summary>
  59. private PosSizableRect _nodeSelected = PosSizableRect.None;
  60. /// <summary>
  61. /// 变换形式,如:放大、重绘
  62. /// </summary>
  63. private TreatmentType _treatmentType = TreatmentType.Zoom;
  64. private TreatmentType _lasttreatmentType = TreatmentType.None;
  65. /// <summary>
  66. /// 基于原图的框
  67. /// </summary>
  68. private Rectangle _imageRect;
  69. /// <summary>
  70. /// 左上点
  71. /// </summary>
  72. private PointF _luPonit = new PointF(0, 0);
  73. /// <summary>
  74. /// 右下点
  75. /// </summary>
  76. private PointF _rbPonit = new PointF(0, 0);
  77. /// <summary>
  78. /// 起始点
  79. /// </summary>
  80. private PointF _startPoint = new PointF(0, 0);
  81. /// <summary>
  82. /// 鼠标点击点
  83. /// </summary>
  84. private PointF _mouseDownPoint = new PointF(0, 0);
  85. /// <summary>
  86. /// 允许画框
  87. /// </summary>
  88. private bool _allawDraw;
  89. /// <summary>
  90. /// 鼠标按下
  91. /// </summary>
  92. private bool _mIsClick;
  93. /// <summary>
  94. /// 鼠标移动
  95. /// </summary>
  96. private bool _isMouseMove;
  97. private int _i;
  98. /// <summary>
  99. /// 竖向缩放比
  100. /// </summary>
  101. public float Hrate = 1; //竖向缩放比
  102. /// <summary>
  103. /// 横向缩放比
  104. /// </summary>
  105. public float Wrate = 1; //横向缩放比
  106. private Color _rectColor = Color.Red;
  107. /// <summary>
  108. /// 是否微调
  109. /// </summary>
  110. private bool _isFirstZoom = false;
  111. /// <summary>
  112. /// 适应屏幕的横向缩放比
  113. /// </summary>
  114. private float _FitWrate;
  115. /// <summary>
  116. /// 适应屏幕的纵向缩放比
  117. /// </summary>
  118. private float _FitHrate;
  119. #endregion
  120. #region 属性
  121. /// <summary>
  122. /// 是否是微调状态
  123. /// </summary>
  124. public bool IsFineTuring // 是否是微调状态
  125. => _nodeSelected != PosSizableRect.None;
  126. /// <summary>
  127. /// 基于原图的框
  128. /// </summary>
  129. public Rectangle ImageRect //基于原图的框
  130. {
  131. get
  132. {
  133. int x = (int)Math.Round((_luPonit.X - _startPoint.X) / Wrate);
  134. int y = (int)Math.Round((_luPonit.Y - _startPoint.Y) / Hrate);
  135. int width = (int)Math.Round((_rbPonit.X - _luPonit.X) / Wrate);
  136. int height = (int)Math.Round((_rbPonit.Y - _luPonit.Y) / Wrate);
  137. Rectangle rect = new Rectangle(x, y, width, height);
  138. Rectangle imageRect = new Rectangle(0, 0, _image == null ? 0 : _image.Width, _image == null ? 0 : _image.Height);
  139. _imageRect = Rectangle.Intersect(rect, imageRect);
  140. if (_imageRect != rect)
  141. {
  142. _luPonit.X = (int)(_imageRect.X * Wrate + _startPoint.X);
  143. _luPonit.Y = (int)(_imageRect.Y * Hrate + _startPoint.Y);
  144. _rbPonit.X = (int)(_imageRect.Width * Wrate + _luPonit.X);
  145. _rbPonit.Y = (int)(_imageRect.Height * Hrate + _luPonit.Y);
  146. }
  147. return _imageRect;
  148. }
  149. set
  150. {
  151. if (_imageRect != value)
  152. {
  153. _luPonit.X = (int)(value.X * Wrate + _startPoint.X);
  154. _luPonit.Y = (int)(value.Y * Hrate + _startPoint.Y);
  155. _rbPonit.X = (int)(value.Width * Wrate + _luPonit.X);
  156. _rbPonit.Y = (int)(value.Height * Hrate + _luPonit.Y);
  157. }
  158. Invalidate();
  159. }
  160. }
  161. /// <summary>
  162. /// 是否保持图片比例不变
  163. /// </summary>
  164. public bool BIsStretch
  165. {
  166. get;
  167. set;
  168. }
  169. /// <summary>
  170. /// 是否是微调状态
  171. /// </summary>
  172. public bool IsFirstZoom // 是否是微调状态
  173. {
  174. get { return _isFirstZoom; }
  175. set { _isFirstZoom = value; }
  176. }
  177. /// <summary>
  178. /// 允许画框
  179. /// </summary>
  180. public bool AllawDraw
  181. {
  182. get
  183. {
  184. return _allawDraw;
  185. }
  186. set
  187. {
  188. _allawDraw = value;
  189. _treatmentType = _allawDraw ? TreatmentType.Draw : TreatmentType.Zoom;
  190. }
  191. }
  192. public Color RectColor
  193. {
  194. get
  195. {
  196. return _rectColor;
  197. }
  198. set
  199. {
  200. _rectColor = value;
  201. }
  202. }
  203. /// <summary>
  204. /// 横向缩放比
  205. /// </summary>
  206. public float ZoomHrate
  207. {
  208. get
  209. {
  210. return Hrate;
  211. }
  212. }
  213. /// <summary>
  214. /// /纵向缩放比
  215. /// </summary>
  216. public float ZoomWrate
  217. {
  218. get
  219. {
  220. return Wrate;
  221. }
  222. }
  223. /// <summary>
  224. /// 图片起始点
  225. /// </summary>
  226. public PointF StartPoint
  227. {
  228. get
  229. {
  230. return _startPoint;
  231. }
  232. set
  233. {
  234. _startPoint = value;
  235. }
  236. }
  237. /// <summary>
  238. /// 鼠标点击点
  239. /// </summary>
  240. public PointF MouseDownPoint
  241. {
  242. get
  243. {
  244. return _mouseDownPoint;
  245. }
  246. }
  247. #endregion
  248. #region 重写
  249. protected override void OnPaint(PaintEventArgs e)
  250. {
  251. try
  252. {
  253. if (_image != null)
  254. {
  255. using (Bitmap imageToDraw = (Bitmap)_image.Clone())
  256. {
  257. Graphics g = e.Graphics;
  258. g.SmoothingMode = SmoothingMode.HighQuality;
  259. g.CompositingQuality = CompositingQuality.HighQuality;
  260. g.InterpolationMode = InterpolationMode.HighQualityBicubic;
  261. int width = (int)Math.Round(_image.Width * Wrate);
  262. int height = (int)Math.Round(_image.Height * Hrate);
  263. g.DrawImage(imageToDraw, new Rectangle((int)Math.Round(_startPoint.X), (int)Math.Round(_startPoint.Y), width, height));
  264. g.DrawRectangle(new Pen(_rectColor, 1), _fineTuningRect.GetRectByF(new RectangleF(_luPonit.X, _luPonit.Y, (_rbPonit.X - _luPonit.X), (_rbPonit.Y - _luPonit.Y))));
  265. //g.DrawLine(new Pen(_rectColor,1),point1,point2);
  266. if (DrawOriginalPathEvent != null)
  267. {
  268. DrawOriginalPathEvent(g);
  269. }
  270. if (DrawDrivingPathEvent != null)
  271. {
  272. DrawDrivingPathEvent(g);
  273. }
  274. }
  275. }
  276. }
  277. finally
  278. {
  279. base.OnPaint(e);
  280. }
  281. }
  282. protected override void OnKeyDown(KeyEventArgs e)
  283. {
  284. if (e.KeyCode == Keys.ControlKey && _i == 0)
  285. {
  286. _lasttreatmentType = _treatmentType;
  287. SetZoom();
  288. _i++;
  289. }
  290. if (e.Control && e.KeyCode == Keys.R)
  291. {
  292. FitToScreen();
  293. }
  294. base.OnKeyDown(e);
  295. }
  296. protected override void OnKeyUp(KeyEventArgs e)
  297. {
  298. if (e.KeyCode == Keys.ControlKey)
  299. {
  300. _i = 0;
  301. if (_lasttreatmentType != TreatmentType.None)
  302. _treatmentType = _lasttreatmentType;
  303. }
  304. base.OnKeyUp(e);
  305. }
  306. protected override void OnMouseDown(MouseEventArgs e)
  307. {
  308. if (e.Button == MouseButtons.Right)
  309. {
  310. return;
  311. }
  312. _isMouseMove = false;
  313. _mouseDownPoint = new Point(e.X, e.Y);
  314. if (_image == null) return;//图片不为空
  315. if (e.X < _startPoint.X || // left
  316. e.X > _startPoint.X + Math.Round(_image.Width * Wrate) || // right
  317. e.Y < _startPoint.Y || // top
  318. e.Y > _startPoint.Y + Math.Round(_image.Height * Hrate)) // buttom
  319. return; //且鼠标在图片内
  320. _nodeSelected = _fineTuningRect.GetNodeSelectable(new Point(e.X, e.Y), _luPonit, _rbPonit);
  321. if (e.Button == MouseButtons.Left)
  322. _mIsClick = true;
  323. }
  324. protected override void OnMouseUp(MouseEventArgs e)
  325. {
  326. if (e.Button == MouseButtons.Right)
  327. {
  328. return;
  329. }
  330. if (_treatmentType != TreatmentType.Zoom)
  331. if (AfterDrawEvent != null)
  332. AfterDrawEvent(_isMouseMove, e.Button == MouseButtons.Right);
  333. _mIsClick = false;
  334. }
  335. protected override void OnMouseMove(MouseEventArgs e)
  336. {
  337. _isMouseMove = true;
  338. PosSizableRect r = _fineTuningRect.GetNodeSelectable(new Point(e.X, e.Y), _luPonit, _rbPonit);
  339. if (_image == null) return;
  340. //if (!_mIsClick && _treatmentType != TreatmentType.Zoom)
  341. //{
  342. // Cursor = _fineTuningRect.GetCursor(r);
  343. // if (r != PosSizableRect.None)
  344. // SetFineTuring();
  345. // else
  346. // SetDraw();
  347. // return;
  348. //}
  349. if (_mIsClick)
  350. {
  351. switch (_treatmentType)
  352. {
  353. case TreatmentType.Zoom:
  354. ZoomMouseMove(e);
  355. break;
  356. case TreatmentType.Draw:
  357. //DrawMouseMove(e); //鼠标移动画方框
  358. break;
  359. case TreatmentType.FineTuring:
  360. //FineTuringMouseMove(e); //对鼠标画的方框进行微调
  361. break;
  362. }
  363. }
  364. else
  365. {
  366. if (MouseMoveTooltipEvent != null)
  367. {
  368. //超出图片不显示气泡
  369. if (e.X >= _startPoint.X && e.X <= (_startPoint.X + _image.Width * Wrate) && e.Y >= _startPoint.Y && e.Y <= _startPoint.Y + _image.Height * Hrate)
  370. {
  371. MouseMoveTooltipEvent(e);
  372. }
  373. }
  374. }
  375. }
  376. /// <summary>
  377. /// 鼠标滚轮事件
  378. /// </summary>
  379. /// <param name="e"></param>
  380. protected override void OnMouseWheel(MouseEventArgs e)
  381. {
  382. if (_image == null) return;
  383. switch (_treatmentType)
  384. {
  385. case TreatmentType.Zoom:
  386. ZoomMouseWheel(e);
  387. break;
  388. case TreatmentType.Draw:
  389. //DrawMouseWheel(e); //画框模式下,鼠标滚轮变化执行的动作
  390. break;
  391. }
  392. }
  393. protected override void OnMouseEnter(EventArgs e)
  394. {
  395. Focus();
  396. }
  397. #endregion
  398. #region 内部方法
  399. /// <summary>
  400. ///图片适应屏幕
  401. /// </summary>
  402. private void FitToScreen()
  403. {
  404. if (_image != null)
  405. {
  406. if (BIsStretch)
  407. {
  408. Hrate = ((float)(Height)) / (_image.Height);
  409. Wrate = ((float)(Width)) / (_image.Width);
  410. }
  411. else
  412. {
  413. Hrate = Wrate = Math.Min(((float)(Width)) / (_image.Width), ((float)(Height)) / (_image.Height));
  414. }
  415. _FitHrate = Hrate;
  416. _FitWrate = Wrate;
  417. float x = (Width - (_image.Width * Wrate)) / 2;
  418. float y = (Height - (_image.Height * Hrate)) / 2;
  419. _startPoint = new PointF(x, y);
  420. }
  421. Invalidate();
  422. }
  423. /// <summary>
  424. /// 鼠标移动画框
  425. /// </summary>
  426. /// <param name="e"></param>
  427. private void DrawMouseMove(MouseEventArgs e)
  428. {
  429. _luPonit.X = Math.Min(_mouseDownPoint.X, e.X);
  430. _luPonit.Y = Math.Min(_mouseDownPoint.Y, e.Y);
  431. _rbPonit.X = Math.Max(_mouseDownPoint.X, e.X);
  432. _rbPonit.Y = Math.Max(_mouseDownPoint.Y, e.Y);
  433. Invalidate();
  434. }
  435. private void DrawMouseWheel(MouseEventArgs e)
  436. {
  437. MouseWheelDrawEvent?.Invoke(this, e);
  438. }
  439. /// <summary>
  440. /// 鼠标移动图片
  441. /// </summary>
  442. /// <param name="e"></param>
  443. private void ZoomMouseMove(MouseEventArgs e)
  444. {
  445. _startPoint.X += e.X - _mouseDownPoint.X;
  446. _startPoint.Y += e.Y - _mouseDownPoint.Y;
  447. _luPonit.X += e.X - _mouseDownPoint.X;
  448. _luPonit.Y += e.Y - _mouseDownPoint.Y;
  449. _rbPonit.X += e.X - _mouseDownPoint.X;
  450. _rbPonit.Y += e.Y - _mouseDownPoint.Y;
  451. _mouseDownPoint = new PointF(e.X, e.Y);
  452. Invalidate();
  453. }
  454. /// <summary>
  455. /// 鼠标滚轮缩放图片
  456. /// </summary>
  457. /// <param name="e"></param>
  458. private void ZoomMouseWheel(MouseEventArgs e)
  459. {
  460. if (e.X >= _startPoint.X && e.X <= (_startPoint.X + _image.Width * Wrate) && e.Y >= _startPoint.Y && e.Y <= _startPoint.Y + _image.Height * Hrate)
  461. {
  462. float imageX = (e.X - _startPoint.X) / Wrate;
  463. float imageY = (e.Y - _startPoint.Y) / Hrate;
  464. PointF firstLu = new PointF((e.X - _luPonit.X) / Wrate, (e.Y - _luPonit.Y) / Hrate);
  465. PointF firstRb = new PointF((e.X - _rbPonit.X) / Wrate, (e.Y - _rbPonit.Y) / Hrate);
  466. float rate = 1;
  467. if (e.Delta > 0)
  468. {
  469. if (Math.Max(Wrate, Hrate) <= 10)
  470. {
  471. rate = 1.15F;
  472. }
  473. }
  474. else
  475. {
  476. if (Math.Min(Wrate, Hrate) > Math.Max(_FitWrate, _FitHrate))
  477. {
  478. rate = 0.85F;
  479. }
  480. }
  481. if (rate == 1) return;
  482. Hrate *= rate;
  483. Wrate *= rate;
  484. _luPonit.X = e.X - firstLu.X * Wrate;
  485. _luPonit.Y = e.Y - firstLu.Y * Hrate;
  486. _rbPonit.X = e.X - firstRb.X * Wrate;
  487. _rbPonit.Y = e.Y - firstRb.Y * Hrate;
  488. _startPoint = new PointF(e.X - imageX * Wrate, e.Y - imageY * Hrate);
  489. Invalidate();
  490. }
  491. }
  492. private void FineTuringMouseMove(MouseEventArgs e)
  493. {
  494. PointF firstLu = new PointF(_luPonit.X, _luPonit.Y);
  495. PointF firstRb = new PointF(_rbPonit.X, _rbPonit.Y);
  496. switch (_nodeSelected)
  497. {
  498. case PosSizableRect.LeftUp:
  499. _luPonit.X += e.X - _mouseDownPoint.X;
  500. _luPonit.Y += e.Y - _mouseDownPoint.Y;
  501. break;
  502. case PosSizableRect.LeftMiddle:
  503. _luPonit.X += e.X - _mouseDownPoint.X;
  504. break;
  505. case PosSizableRect.LeftBottom:
  506. _luPonit.X += e.X - _mouseDownPoint.X;
  507. _rbPonit.Y += e.Y - _mouseDownPoint.Y;
  508. break;
  509. case PosSizableRect.BottomMiddle:
  510. _rbPonit.Y += e.Y - _mouseDownPoint.Y;
  511. break;
  512. case PosSizableRect.RightBottom:
  513. _rbPonit.X += e.X - _mouseDownPoint.X;
  514. _rbPonit.Y += e.Y - _mouseDownPoint.Y;
  515. break;
  516. case PosSizableRect.RightMiddle:
  517. _rbPonit.X += e.X - _mouseDownPoint.X;
  518. break;
  519. case PosSizableRect.RightUp:
  520. _rbPonit.X += e.X - _mouseDownPoint.X;
  521. _luPonit.Y += e.Y - _mouseDownPoint.Y;
  522. break;
  523. case PosSizableRect.UpMiddle:
  524. _luPonit.Y += e.Y - _mouseDownPoint.Y;
  525. break;
  526. case PosSizableRect.TopIn:
  527. _luPonit.X += e.X - _mouseDownPoint.X;
  528. _luPonit.Y += e.Y - _mouseDownPoint.Y;
  529. _rbPonit.X += e.X - _mouseDownPoint.X;
  530. _rbPonit.Y += e.Y - _mouseDownPoint.Y;
  531. break;
  532. case PosSizableRect.ButtonIn:
  533. _luPonit.X += e.X - _mouseDownPoint.X;
  534. _luPonit.Y += e.Y - _mouseDownPoint.Y;
  535. _rbPonit.X += e.X - _mouseDownPoint.X;
  536. _rbPonit.Y += e.Y - _mouseDownPoint.Y;
  537. break;
  538. }
  539. _mouseDownPoint.X = e.X;
  540. _mouseDownPoint.Y = e.Y;
  541. if ((_rbPonit.X - _luPonit.X) < 5 || (_rbPonit.Y - _luPonit.Y) < 5)
  542. {
  543. _luPonit = new PointF(firstLu.X, firstLu.Y);
  544. _rbPonit = new PointF(firstRb.X, firstRb.Y);
  545. }
  546. Invalidate();
  547. }
  548. /// <summary>
  549. /// 控件尺寸改变
  550. /// </summary>
  551. /// <param name="sender"></param>
  552. /// <param name="e"></param>
  553. private void PicExControl_SizeChanged(object sender, EventArgs e)
  554. {
  555. if (_image != null)
  556. {
  557. if (BIsStretch)
  558. {
  559. Hrate = ((float)(Height)) / (_image.Height);
  560. Wrate = ((float)(Width)) / (_image.Width);
  561. }
  562. else
  563. {
  564. Hrate = Wrate = Math.Min(((float)(Width)) / (_image.Width), ((float)(Height)) / (_image.Height));
  565. }
  566. }
  567. Invalidate();
  568. }
  569. /// <summary>
  570. /// 设置画框模式
  571. /// </summary>
  572. private void SetDraw()
  573. {
  574. Cursor = Cursors.Default;
  575. _treatmentType = _allawDraw ? TreatmentType.Draw : TreatmentType.Zoom;
  576. Invalidate();
  577. }
  578. /// <summary>
  579. ///设置微调模式
  580. /// </summary>
  581. private void SetFineTuring()
  582. {
  583. _treatmentType = _allawDraw ? TreatmentType.FineTuring : TreatmentType.Zoom;
  584. Invalidate();
  585. }
  586. #endregion
  587. #region 公用方法
  588. /// <summary>
  589. /// 获取图片
  590. /// </summary>
  591. /// <returns></returns>
  592. public Image GetImage()
  593. {
  594. return _image;
  595. }
  596. /// <summary>
  597. /// 设置图片
  598. /// </summary>
  599. /// <param name="bitmap">图片</param>
  600. /// <param name="isFirst">适应屏幕</param>
  601. /// <param name="isDeleteRect">原图的框</param>
  602. /// <param name="zoom">缩放比例</param>
  603. public void SetImage(Image bitmap, bool isFirst, bool isDeleteRect = false, int zoom = 1)
  604. {
  605. if (_image != null)
  606. {
  607. _image.Dispose();
  608. _image = null;
  609. }
  610. if (bitmap == null)
  611. {
  612. return;
  613. }
  614. _image = (Image)bitmap.Clone();
  615. if (isFirst)
  616. {
  617. if (_isFirstZoom)
  618. FitToScreen();
  619. else
  620. {
  621. Hrate = zoom; //竖向缩放比
  622. Wrate = zoom; //横向缩放比
  623. _startPoint = new PointF((Width - _image.Width * Wrate) / 2, (Height - _image.Height * Hrate) / 2);
  624. }
  625. SetDraw();
  626. }
  627. if (isDeleteRect)
  628. ImageRect = new Rectangle(0, 0, 0, 0);
  629. Refresh();
  630. bitmap.Dispose();
  631. Invalidate();
  632. }
  633. /// <summary>
  634. /// 获取鼠标点击的点
  635. /// </summary>
  636. /// <returns></returns>
  637. public Point GetClickPoint()
  638. {
  639. return new Point((int)((_mouseDownPoint.X - _startPoint.X) / Wrate), (int)((_mouseDownPoint.Y - _startPoint.Y) / Hrate));
  640. }
  641. /// <summary>
  642. ///进入缩放模式
  643. /// </summary>
  644. public void SetZoom()
  645. {
  646. _treatmentType = TreatmentType.Zoom;
  647. Invalidate();
  648. }
  649. #endregion
  650. }
  651. /// <summary>
  652. /// 微调类
  653. /// </summary>
  654. public class FineTuningRect
  655. {
  656. public PicExControl FatherControl;
  657. private const int SizeNodeRect = 10;
  658. public Rectangle GetRectByF(RectangleF rectf)
  659. {
  660. return new Rectangle((int)rectf.X, (int)rectf.Y, (int)rectf.Width, (int)rectf.Height);
  661. }
  662. private RectangleF GetRect(PosSizableRect p, PointF luPointF, PointF rbPointF)
  663. {
  664. switch (p)
  665. {
  666. //// 点
  667. case PosSizableRect.LeftUp:
  668. return new RectangleF(luPointF.X - SizeNodeRect / 2, luPointF.Y - SizeNodeRect / 2, SizeNodeRect, SizeNodeRect);
  669. case PosSizableRect.LeftBottom:
  670. return new RectangleF(luPointF.X - SizeNodeRect / 2, rbPointF.Y - SizeNodeRect / 2, SizeNodeRect, SizeNodeRect);
  671. case PosSizableRect.RightUp:
  672. return new RectangleF(rbPointF.X - SizeNodeRect / 2, luPointF.Y - SizeNodeRect / 2, SizeNodeRect, SizeNodeRect);
  673. case PosSizableRect.RightBottom:
  674. return new RectangleF(rbPointF.X - SizeNodeRect / 2, rbPointF.Y - SizeNodeRect / 2, SizeNodeRect, SizeNodeRect);
  675. case PosSizableRect.TopIn:
  676. return new RectangleF(luPointF.X + (rbPointF.X - luPointF.X) / 6 - SizeNodeRect / 2, luPointF.Y - SizeNodeRect / 2, (rbPointF.X - luPointF.X) / 3, SizeNodeRect);
  677. case PosSizableRect.ButtonIn:
  678. return new RectangleF(luPointF.X + (rbPointF.X - luPointF.X) / 6 - SizeNodeRect / 2, rbPointF.Y - SizeNodeRect / 2, (rbPointF.X - luPointF.X) / 3, SizeNodeRect);
  679. //// 线
  680. case PosSizableRect.LeftMiddle:
  681. return new RectangleF(luPointF.X, luPointF.Y, SizeNodeRect, rbPointF.Y - luPointF.Y);
  682. case PosSizableRect.UpMiddle:
  683. return new RectangleF(luPointF.X, luPointF.Y, rbPointF.X - luPointF.X, SizeNodeRect);
  684. case PosSizableRect.RightMiddle:
  685. return new RectangleF(rbPointF.X, luPointF.Y, SizeNodeRect, rbPointF.Y - luPointF.Y);
  686. case PosSizableRect.BottomMiddle:
  687. return new RectangleF(luPointF.X, rbPointF.Y, rbPointF.X - luPointF.X, SizeNodeRect);
  688. default:
  689. return new RectangleF();
  690. }
  691. }
  692. public PosSizableRect GetNodeSelectable(Point p, PointF luPointF, PointF rbPointF)
  693. {
  694. foreach (PosSizableRect r in Enum.GetValues(typeof(PosSizableRect)))
  695. {
  696. if (r == PosSizableRect.LeftMiddle || r == PosSizableRect.UpMiddle || r == PosSizableRect.RightMiddle ||
  697. r == PosSizableRect.BottomMiddle)
  698. continue;
  699. if (GetRect(r, luPointF, rbPointF).Contains(p))
  700. {
  701. return r;
  702. }
  703. }
  704. foreach (PosSizableRect r in Enum.GetValues(typeof(PosSizableRect)))
  705. {
  706. if (GetRect(r, luPointF, rbPointF).Contains(p))
  707. {
  708. return r;
  709. }
  710. }
  711. return PosSizableRect.None;
  712. }
  713. public Cursor GetCursor(PosSizableRect r)
  714. {
  715. switch (r)
  716. {
  717. case PosSizableRect.LeftUp:
  718. return Cursors.SizeNWSE;
  719. case PosSizableRect.LeftMiddle:
  720. return Cursors.SizeWE;
  721. case PosSizableRect.LeftBottom:
  722. return Cursors.SizeNESW;
  723. case PosSizableRect.BottomMiddle:
  724. return Cursors.SizeNS;
  725. case PosSizableRect.RightUp:
  726. return Cursors.SizeNESW;
  727. case PosSizableRect.RightBottom:
  728. return Cursors.SizeNWSE;
  729. case PosSizableRect.RightMiddle:
  730. return Cursors.SizeWE;
  731. case PosSizableRect.UpMiddle:
  732. return Cursors.SizeNS;
  733. case PosSizableRect.TopIn:
  734. return Cursors.SizeAll;
  735. case PosSizableRect.ButtonIn:
  736. return Cursors.SizeAll;
  737. default:
  738. return Cursors.Default;
  739. }
  740. }
  741. }
  742. public enum TreatmentType
  743. {
  744. Zoom,
  745. Draw,
  746. FineTuring,
  747. None
  748. }
  749. public enum PosSizableRect
  750. {
  751. UpMiddle,
  752. LeftMiddle,
  753. LeftBottom,
  754. LeftUp,
  755. RightUp,
  756. RightMiddle,
  757. RightBottom,
  758. BottomMiddle,
  759. None,
  760. TopIn,
  761. ButtonIn
  762. };
  763. }