winform 可缩放,拖拽,画框,微调框的 pictureBox
来源:互联网 发布:驱动软件哪个好 编辑:程序博客网 时间:2024/05/16 04:52
using System;using System.Drawing;using System.Drawing.Drawing2D;using System.Windows.Forms;namespace MyControl{ /// <summary> /// 支持缩放和画框以及对框进行微调的图片显示控件 /// </summary> public partial class PicExControl : UserControl { public PicExControl() { InitializeComponent(); _fineTuningRect = new FineTuningRect {FatherControl = this}; SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer, true); } #region 字段和事件 public delegate void MouseWheelDraw(object sender, MouseEventArgs e); //显示树 public event MouseWheelDraw MouseWheelDrawEvent; public delegate void AfterDraw(bool isMove,bool isRight); public event AfterDraw AfterDrawEvent; private Image _image; //原图 private FineTuningRect _fineTuningRect; private PosSizableRect _nodeSelected = PosSizableRect.None; private TreatmentType _treatmentType = TreatmentType.Zoom; private TreatmentType _lasttreatmentType = TreatmentType.None; private Rectangle _imageRect; private PointF _luPonit = new PointF(0,0); private PointF _rbPonit = new PointF(0,0); private PointF _startPoint = new PointF(0, 0); private PointF _mouseDownPoint = new PointF(0, 0); private bool _allawDraw; private bool _mIsClick; private bool _isMouseMove; private int _i; public float Hrate = 1; //竖向缩放比 public float Wrate = 1; //横向缩放比 private Color _rectColor = Color.Red; private bool _isFirstZoom = true; #endregion #region 属性 public bool IsFineTuring // 是否是微调状态 => _nodeSelected != PosSizableRect.None; public Rectangle ImageRect //基于原图的框 { get { int x = (int)Math.Round((_luPonit.X - _startPoint.X) / Wrate); int y = (int)Math.Round((_luPonit.Y - _startPoint.Y) / Hrate); int width = (int)Math.Round((_rbPonit.X - _luPonit.X) / Wrate); int height = (int)Math.Round((_rbPonit.Y - _luPonit.Y) / Wrate); Rectangle rect = new Rectangle(x, y, width, height); Rectangle imageRect = new Rectangle(0, 0, _image == null ? 0 : _image.Width, _image == null ? 0 : _image.Height); _imageRect = Rectangle.Intersect(rect, imageRect); if (_imageRect != rect) { _luPonit.X = (int)(_imageRect.X * Wrate + _startPoint.X); _luPonit.Y = (int)(_imageRect.Y * Hrate + _startPoint.Y); _rbPonit.X = (int)(_imageRect.Width * Wrate + _luPonit.X); _rbPonit.Y = (int)(_imageRect.Height * Hrate + _luPonit.Y); } return _imageRect; } set { if (_imageRect != value) { _luPonit.X = (int) (value.X*Wrate + _startPoint.X); _luPonit.Y = (int) (value.Y*Hrate + _startPoint.Y); _rbPonit.X = (int) (value.Width*Wrate + _luPonit.X); _rbPonit.Y = (int) (value.Height*Hrate + _luPonit.Y); } Invalidate(); } } /// <summary> /// 是否保持图片比例不变 /// </summary> public bool BIsStretch { get; set; } public bool IsFirstZoom // 是否是微调状态 { get { return _isFirstZoom; } set { _isFirstZoom = value; } } /// <summary> /// 允许画框 /// </summary> public bool AllawDraw { get { return _allawDraw; } set { _treatmentType = _allawDraw ? TreatmentType.Draw : TreatmentType.Zoom; _allawDraw = value; } } public Color RectColor { get { return _rectColor; } set { _rectColor = value; } } #endregion #region 重写 protected override void OnPaint(PaintEventArgs e) { try { if (_image != null) { using (Bitmap imageToDraw = (Bitmap)_image.Clone()) { Graphics g = e.Graphics; g.SmoothingMode = SmoothingMode.HighQuality; g.CompositingQuality = CompositingQuality.HighQuality; g.InterpolationMode = InterpolationMode.HighQualityBicubic; int width = (int)Math.Round(_image.Width * Wrate); int height = (int)Math.Round(_image.Height * Hrate); g.DrawImage(imageToDraw, new Rectangle((int)Math.Round(_startPoint.X), (int)Math.Round(_startPoint.Y), width, height)); g.DrawRectangle(new Pen(_rectColor,1),_fineTuningRect.GetRectByF(new RectangleF(_luPonit.X,_luPonit.Y,(_rbPonit.X - _luPonit.X),(_rbPonit.Y - _luPonit.Y)))); } } } finally { base.OnPaint(e); } } protected override void OnKeyDown(KeyEventArgs e) { if (e.KeyCode == Keys.ControlKey && _i == 0) { _lasttreatmentType = _treatmentType; SetZoom(); _i++; } if (e.Control && e.KeyCode == Keys.R) { FitToScreen(); } base.OnKeyDown(e); } protected override void OnKeyUp(KeyEventArgs e) { if (e.KeyCode == Keys.ControlKey) { _i = 0; if (_lasttreatmentType != TreatmentType.None) _treatmentType = _lasttreatmentType; } base.OnKeyUp(e); } protected override void OnMouseDown(MouseEventArgs e) { _isMouseMove = false; _mouseDownPoint = new Point(e.X, e.Y); if (_image == null) return;//图片不为空 if (e.X < _startPoint.X || // left e.X > _startPoint.X + Math.Round(_image.Width * Wrate) || // right e.Y < _startPoint.Y || // top e.Y > _startPoint.Y + Math.Round(_image.Height * Hrate)) // buttom return; //且鼠标在图片内 _nodeSelected = _fineTuningRect.GetNodeSelectable(new Point(e.X, e.Y), _luPonit, _rbPonit); if (e.Button == MouseButtons.Left) _mIsClick = true; } protected override void OnMouseUp(MouseEventArgs e) { if (_treatmentType != TreatmentType.Zoom) if (AfterDrawEvent != null) AfterDrawEvent(_isMouseMove, e.Button == MouseButtons.Right); _mIsClick = false; } protected override void OnMouseMove(MouseEventArgs e) { _isMouseMove = true; PosSizableRect r = _fineTuningRect.GetNodeSelectable(new Point(e.X, e.Y), _luPonit, _rbPonit); if (_image == null) return; if (!_mIsClick && _treatmentType!= TreatmentType.Zoom) { Cursor = _fineTuningRect.GetCursor(r); if (r != PosSizableRect.None) SetFineTuring(); else SetDraw(); return; } if(_mIsClick) { switch (_treatmentType) { case TreatmentType.Zoom: ZoomMouseMove(e); break; case TreatmentType.Draw: DrawMouseMove(e); break; case TreatmentType.FineTuring: FineTuringMouseMove(e); break; } } } protected override void OnMouseWheel(MouseEventArgs e) { if (_image == null) return; switch (_treatmentType) { case TreatmentType.Zoom: ZoomMouseWheel(e); break; case TreatmentType.Draw: DrawMouseWheel(e); break; } } protected override void OnMouseEnter(EventArgs e) { Focus(); } #endregion #region 内部方法 private void FitToScreen() { if (_image != null) { if (BIsStretch) { Hrate = ((float)(Height)) / (_image.Height); Wrate = ((float)(Width)) / (_image.Width); } else { Hrate = Wrate = Math.Min(((float)(Width)) / (_image.Width), ((float)(Height)) / (_image.Height)); } float x = (Width - (_image.Width * Wrate)) / 2; float y = (Height - (_image.Height * Hrate)) / 2; _startPoint = new PointF(x, y); } Invalidate(); } private void DrawMouseMove(MouseEventArgs e) { _luPonit.X = Math.Min(_mouseDownPoint.X, e.X); _luPonit.Y = Math.Min(_mouseDownPoint.Y, e.Y); _rbPonit.X = Math.Max(_mouseDownPoint.X, e.X); _rbPonit.Y = Math.Max(_mouseDownPoint.Y, e.Y); Invalidate(); } private void DrawMouseWheel(MouseEventArgs e) { MouseWheelDrawEvent?.Invoke(this, e); } private void ZoomMouseMove(MouseEventArgs e) { _startPoint.X += e.X - _mouseDownPoint.X; _startPoint.Y += e.Y - _mouseDownPoint.Y; _luPonit.X += e.X - _mouseDownPoint.X; _luPonit.Y += e.Y - _mouseDownPoint.Y; _rbPonit.X += e.X - _mouseDownPoint.X; _rbPonit.Y += e.Y - _mouseDownPoint.Y; _mouseDownPoint = new PointF(e.X, e.Y); Invalidate(); } private void ZoomMouseWheel(MouseEventArgs e) { if (e.X >= _startPoint.X && e.X <= (_startPoint.X + _image.Width * Wrate) && e.Y >= _startPoint.Y && e.Y <= _startPoint.Y + _image.Height * Hrate) { float imageX = (e.X - _startPoint.X) / Wrate; float imageY = (e.Y - _startPoint.Y) / Hrate; PointF firstLu = new PointF((e.X - _luPonit.X) / Wrate, (e.Y - _luPonit.Y) / Hrate); PointF firstRb = new PointF((e.X - _rbPonit.X) / Wrate, (e.Y - _rbPonit.Y) / Hrate); float rate = 1; if (e.Delta > 0) { if (Math.Max(Wrate, Hrate) <= 10) { rate = 1.15F; } } else { if (Math.Min(Wrate, Hrate) >= 0.1) { rate = 0.85F; } } if (rate == 1) return; Hrate *= rate; Wrate *= rate; _luPonit.X = e.X - firstLu.X * Wrate; _luPonit.Y = e.Y - firstLu.Y * Hrate; _rbPonit.X = e.X - firstRb.X * Wrate; _rbPonit.Y = e.Y - firstRb.Y * Hrate; _startPoint = new PointF(e.X - imageX * Wrate, e.Y - imageY * Hrate); Invalidate(); } } private void FineTuringMouseMove(MouseEventArgs e) { PointF firstLu = new PointF(_luPonit.X, _luPonit.Y); PointF firstRb = new PointF(_rbPonit.X, _rbPonit.Y); switch (_nodeSelected) { case PosSizableRect.LeftUp: _luPonit.X += e.X - _mouseDownPoint.X; _luPonit.Y += e.Y - _mouseDownPoint.Y; break; case PosSizableRect.LeftMiddle: _luPonit.X += e.X - _mouseDownPoint.X; break; case PosSizableRect.LeftBottom: _luPonit.X += e.X - _mouseDownPoint.X; _rbPonit.Y += e.Y - _mouseDownPoint.Y; break; case PosSizableRect.BottomMiddle: _rbPonit.Y += e.Y - _mouseDownPoint.Y; break; case PosSizableRect.RightBottom: _rbPonit.X += e.X - _mouseDownPoint.X; _rbPonit.Y += e.Y - _mouseDownPoint.Y; break; case PosSizableRect.RightMiddle: _rbPonit.X += e.X - _mouseDownPoint.X; break; case PosSizableRect.RightUp: _rbPonit.X += e.X - _mouseDownPoint.X; _luPonit.Y += e.Y - _mouseDownPoint.Y; break; case PosSizableRect.UpMiddle: _luPonit.Y += e.Y - _mouseDownPoint.Y; break; case PosSizableRect.TopIn: _luPonit.X += e.X - _mouseDownPoint.X; _luPonit.Y += e.Y - _mouseDownPoint.Y; _rbPonit.X += e.X - _mouseDownPoint.X; _rbPonit.Y += e.Y - _mouseDownPoint.Y; break; case PosSizableRect.ButtonIn: _luPonit.X += e.X - _mouseDownPoint.X; _luPonit.Y += e.Y - _mouseDownPoint.Y; _rbPonit.X += e.X - _mouseDownPoint.X; _rbPonit.Y += e.Y - _mouseDownPoint.Y; break; } _mouseDownPoint.X = e.X; _mouseDownPoint.Y = e.Y; if ((_rbPonit.X - _luPonit.X) < 5 || (_rbPonit.Y - _luPonit.Y) < 5) { _luPonit = new PointF(firstLu.X, firstLu.Y); _rbPonit = new PointF(firstRb.X, firstRb.Y); } Invalidate(); } private void PicExControl_SizeChanged(object sender, EventArgs e) { if (_image != null) { if (BIsStretch) { Hrate = ((float)(Height)) / (_image.Height); Wrate = ((float)(Width)) / (_image.Width); } else { Hrate = Wrate = Math.Min(((float)(Width)) / (_image.Width), ((float)(Height)) / (_image.Height)); } } Invalidate(); } private void SetDraw() { Cursor = Cursors.Default; _treatmentType = _allawDraw ? TreatmentType.Draw : TreatmentType.Zoom; Invalidate(); } private void SetFineTuring() { _treatmentType = _allawDraw ? TreatmentType.FineTuring : TreatmentType.Zoom; Invalidate(); } #endregion #region 公用方法 public Image GetImage() { return _image; } public void SetImage(Image bitmap, bool isFirst, bool isDeleteRect = false, int zoom = 1) { if (_image != null) { _image.Dispose(); _image = null; } if (bitmap == null) { return; } _image = (Image)bitmap.Clone(); if (isFirst) { if (_isFirstZoom) FitToScreen(); else { Hrate = zoom; //竖向缩放比 Wrate = zoom; //横向缩放比 _startPoint = new PointF((Width - _image.Width*Wrate) / 2,(Height - _image.Height * Hrate) / 2); } SetDraw(); } if (isDeleteRect) ImageRect = new Rectangle(0, 0, 0, 0); Refresh(); bitmap.Dispose(); Invalidate(); } public Point GetClickPoint() { return new Point((int)((_mouseDownPoint.X - _startPoint.X) / Wrate), (int)((_mouseDownPoint.Y - _startPoint.Y) / Hrate)); } // 进入缩放模式 public void SetZoom() { _treatmentType = TreatmentType.Zoom; Invalidate(); } #endregion } public class FineTuningRect { public PicExControl FatherControl; private const int SizeNodeRect = 10; public Rectangle GetRectByF(RectangleF rectf) { return new Rectangle((int)rectf.X, (int)rectf.Y, (int)rectf.Width, (int)rectf.Height); } private RectangleF GetRect(PosSizableRect p, PointF luPointF, PointF rbPointF) { switch (p) { //// 点 case PosSizableRect.LeftUp: return new RectangleF(luPointF.X - SizeNodeRect / 2, luPointF.Y - SizeNodeRect / 2, SizeNodeRect, SizeNodeRect); case PosSizableRect.LeftBottom: return new RectangleF(luPointF.X - SizeNodeRect / 2, rbPointF.Y - SizeNodeRect / 2, SizeNodeRect, SizeNodeRect); case PosSizableRect.RightUp: return new RectangleF(rbPointF.X - SizeNodeRect / 2, luPointF.Y - SizeNodeRect / 2, SizeNodeRect, SizeNodeRect); case PosSizableRect.RightBottom: return new RectangleF(rbPointF.X - SizeNodeRect / 2, rbPointF.Y - SizeNodeRect / 2, SizeNodeRect, SizeNodeRect); case PosSizableRect.TopIn: return new RectangleF(luPointF.X + (rbPointF.X - luPointF.X) / 6 - SizeNodeRect / 2, luPointF.Y - SizeNodeRect / 2, (rbPointF.X - luPointF.X) / 3, SizeNodeRect); case PosSizableRect.ButtonIn: return new RectangleF(luPointF.X + (rbPointF.X - luPointF.X) / 6 - SizeNodeRect / 2, rbPointF.Y - SizeNodeRect / 2, (rbPointF.X - luPointF.X) / 3, SizeNodeRect); //// 线 case PosSizableRect.LeftMiddle: return new RectangleF(luPointF.X, luPointF.Y, SizeNodeRect, rbPointF.Y - luPointF.Y); case PosSizableRect.UpMiddle: return new RectangleF(luPointF.X, luPointF.Y, rbPointF.X - luPointF.X, SizeNodeRect); case PosSizableRect.RightMiddle: return new RectangleF(rbPointF.X, luPointF.Y, SizeNodeRect, rbPointF.Y - luPointF.Y); case PosSizableRect.BottomMiddle: return new RectangleF(luPointF.X, rbPointF.Y, rbPointF.X - luPointF.X, SizeNodeRect); default: return new RectangleF(); } } public PosSizableRect GetNodeSelectable(Point p, PointF luPointF, PointF rbPointF) { foreach (PosSizableRect r in Enum.GetValues(typeof(PosSizableRect))) { if (r == PosSizableRect.LeftMiddle || r == PosSizableRect.UpMiddle || r == PosSizableRect.RightMiddle || r == PosSizableRect.BottomMiddle) continue; if (GetRect(r, luPointF, rbPointF).Contains(p)) { return r; } } foreach (PosSizableRect r in Enum.GetValues(typeof (PosSizableRect))) { if (GetRect(r, luPointF, rbPointF).Contains(p)) { return r; } } return PosSizableRect.None; } public Cursor GetCursor(PosSizableRect r) { switch (r) { case PosSizableRect.LeftUp: return Cursors.SizeNWSE; case PosSizableRect.LeftMiddle: return Cursors.SizeWE; case PosSizableRect.LeftBottom: return Cursors.SizeNESW; case PosSizableRect.BottomMiddle: return Cursors.SizeNS; case PosSizableRect.RightUp: return Cursors.SizeNESW; case PosSizableRect.RightBottom: return Cursors.SizeNWSE; case PosSizableRect.RightMiddle: return Cursors.SizeWE; case PosSizableRect.UpMiddle: return Cursors.SizeNS; case PosSizableRect.TopIn: return Cursors.SizeAll; case PosSizableRect.ButtonIn: return Cursors.SizeAll; default: return Cursors.Default; } } } public enum TreatmentType { Zoom, Draw, FineTuring, None } public enum PosSizableRect { UpMiddle, LeftMiddle, LeftBottom, LeftUp, RightUp, RightMiddle, RightBottom, BottomMiddle, None, TopIn, ButtonIn };}
0 0
- winform 可缩放,拖拽,画框,微调框的 pictureBox
- c# picturebox图片上画框框或圈圈
- Picturebox实现图片的缩放
- [WINFORM]PictureBox顯示圖片的方式
- winform上创建可拖动缩放的控件
- c# winform pictureBox显示图片,PictureBox控件的Image属性
- c# winform pictureBox显示图片,PictureBox控件的Image属性
- C# winform 另存为picturebox里的图片
- PictureBox 的简单操作 (C# WinForm)
- picturebox 图片缩放
- winform上传照片并处理(包括上传时自动缩放大小以适应picturebox大小,裁剪)
- 可缩放的ImageView
- c# winform pictureBox
- winform PictureBox 图片旋转
- c#中鼠标滚轮对PictureBox的缩放
- c#如何打印picturebox里的图片,winform怎样打印picturebox里的图片
- C# winform 使用滚动条查看PictureBox的大图片
- C#Winform的picturebox控件显示红叉
- openstack 管理三十三
- Java核心技术笔记-第5章
- 初探Lambda表达式-Java多核编程【2】并行与组合行为
- Java default方法
- task:scheduled-tasks cron表达式
- winform 可缩放,拖拽,画框,微调框的 pictureBox
- 【PAT】1057. Stack
- Reinforcement Learning学习笔记(2)
- ionic中循环出来的分类组点击改变背景颜色的实现
- 博客内容摘要及阅读顺序
- c++ primer 练习 2.9、2.10
- python for循环和range内置函数
- Java的数组和list升序,降序,逆序函数Collections.sort和Arrays.sort的使用
- FE