winform的扩展的带有截图功能picturebox
using System; using System.ComponentModel; using System.Diagnostics; using System.Drawing; using System.Windows.Forms; namespace Aping.Common.Windows.Forms { public partial class CutImageBox : System.Windows.Forms.PictureBox { public CutImageBox() { InitializeComponent(); } public CutImageBox(IContainer container) { container.Add(this); InitializeComponent(); } //自定义裁图控件 //线条颜色 #region 字段 private Color borderColor = Color.Red;//线条颜色 private bool canResize = true;//是否能够改变截图框的大小 private int side = 6;//小框框的大小 private int alpha = 50;//遮罩层透明度 private bool showCutArea = true;//是否展示截图框 private Rectangle CutImageArea = new Rectangle(5, 5, 120, 160); private Rectangle[] Lites = new Rectangle[8]; private AreaAlign cutAreaAlign = AreaAlign.Default; private int miniWidth = 120;//最小宽 private int miniHeight = 160;//最小高 private bool ownerDraw = false; private bool autoHide = false; private System.Drawing.Drawing2D.DashStyle dashStyle = System.Drawing.Drawing2D.DashStyle.Dash; #endregion #region 属性 [Description("设置截图框边框的颜色。")] public Color AreaBoderColor { get { return borderColor; } set { borderColor = value; Invalidate(); } } [Description("是否可以改变截图框的大小。")] public bool EnableResize { get { return canResize; } set { canResize = value; } } //小方框的大小 [Description("是否显示截图框,默认为显示。")] public bool ShowCutArea { get { return showCutArea; } set { showCutArea = value; Invalidate(); } } [Description("截图框的透明度,默认值:50。")] public int AreaAlpha { get { return alpha; } set { alpha = value; Invalidate(); } } [Description("截图框加载后显示的位置,默认为左上角。")] public AreaAlign CutAreaAlign { get { return cutAreaAlign; } set { cutAreaAlign = value; switch (cutAreaAlign) { case AreaAlign.Default: CutImageArea = new Rectangle(15, 15, miniWidth, miniHeight); break; case AreaAlign.Center: CutImageArea = new Rectangle((Width - miniWidth) / 2, (Height - miniHeight) / 2, miniWidth, miniHeight); break; case AreaAlign.RightCenter: CutImageArea = new Rectangle(Width - CutImageArea.Width - 15, (Height - miniHeight) / 2, miniWidth, miniHeight); break; case AreaAlign.RightTop: CutImageArea = new Rectangle(Width - CutImageArea.Width - 15, 15, miniWidth, miniHeight); break; case AreaAlign.LeftCenter: CutImageArea = new Rectangle(15, (Height - miniHeight) / 2, miniWidth, miniHeight); break; case AreaAlign.LeftBottom: CutImageArea = new Rectangle(15, Height - CutImageArea.Width - 15, miniWidth, miniHeight); break; case AreaAlign.RightBottom: CutImageArea = new Rectangle(Width - CutImageArea.Width - 15, Height - CutImageArea.Width - 15, miniWidth, miniHeight); break; default: break; } Invalidate(); } } [Description("截图框宽的最小值,默认值:120。")] public int MiniWidth { get { return miniWidth; } set { miniWidth = value; } } [Description("截图框高的最小值,默认值:160。")] public int MiniHeight { get { return miniHeight; } set { miniHeight = value; } } [Description("开启手动绘图,EnableResize 必须开启。")] public bool EnableOwnerDraw { get { return ownerDraw && canResize; } set { ownerDraw = value; Invalidate(); } } [Description("是否在截完图后自动隐藏。")] public bool AutoHide { get { return autoHide; } set { autoHide = value; } } [Description("绘图框边框的样式,不要使用customs。")] public System.Drawing.Drawing2D.DashStyle AreaBorder { get { return dashStyle; } set { if (value != System.Drawing.Drawing2D.DashStyle.Custom)dashStyle = value; Invalidate(); } } #endregion #region 参数 private Point MouseDownPoint; private Point MouseDownPointToScreen; private Point CutImageAreaLocationToScreen; private Point CutImageOldLocation; private Size OldCutImageAreaSize; private MouseDirection mouseDirection = MouseDirection.NONE; private System.Drawing.Point RectStartPoint; private System.Drawing.Point RectEndPoint; #endregion #region 方法 /// <summary> /// 判断某个点是否在指定的区域内 /// </summary> /// <param name="leftup">左上角的点</param> /// <param name="rightdown">右下角的点</param> /// <param name="compare">需要判断的点</param> /// <returns> /// 是 :true 否 false /// </returns> private bool IsInArea(Point leftup, Point rightdown, Point compare) { if (compare.X > leftup.X && compare.Y > leftup.Y && compare.X < rightdown.X && compare.Y < rightdown.Y) { return true; } return false; } /// <summary> /// 判断某个点是否在指定的区域内 /// </summary> /// <param name="leftup">左上角的点</param> /// <param name="width">区域宽</param> /// <param name="height">区域高</param> /// <param name="compare">需要判断的点</param> /// <returns> /// 是 :true 否 false /// </returns> private bool IsInArea(Point leftup, int width, int height, Point compare) { if (compare.X > leftup.X && compare.Y > leftup.Y && compare.X < leftup.X + width && compare.Y < leftup.Y + height) { return true; } return false; } //图像裁剪 public Bitmap GetPartOfImage(Bitmap sourceImg, int width, int height, int offsetX, int offsetY) { Bitmap sourceBitmap = sourceImg; Bitmap resultBitmap = new Bitmap(width, height); using (Graphics g = Graphics.FromImage(resultBitmap)) { Rectangle resultRectangle = new Rectangle(0, 0, width, height); Rectangle sourceRectangle = new Rectangle(0 + offsetX, 0 + offsetY, width, height); //万能的drawImage函数啊,七七八八的参数非常多 普通的图片拉伸 放大 等效果都可以用它来做到。 //第一个参数:原图(被裁剪的图) //第二个参数:目标Image(裁剪后的图) //第三个参数:原图被裁剪的区域 //第四个参数:单位(当然是像素啦) g.DrawImage(sourceBitmap, resultRectangle, sourceRectangle, GraphicsUnit.Pixel); } return resultBitmap; } bool CanMove() { bool flag = true; if (CutImageArea.Width >= Width) flag = false; if (CutImageArea.Height >= Height) flag = false; if (CutImageArea.Width <= MiniWidth) flag = false; if (CutImageArea.Height <= MiniHeight) flag = false; return flag; } #endregion #region 重写的方法 protected override void OnMouseDoubleClick(MouseEventArgs e) { base.OnMouseDoubleClick(e); if (Image == null) throw new ArgumentNullException("aping extends control throws exception error message : image is null"); //处理裁图 Bitmap cutted = GetPartOfImage((Bitmap)Image, CutImageArea.Width, CutImageArea.Height, CutImageArea.X, CutImageArea.Y); Image = cutted; if (autoHide) { Lites = new Rectangle[8]; showCutArea = false; Invalidate(); } if (OnCuttedImage != null) OnCuttedImage(Image); } protected override void CreateHandle() { base.CreateHandle(); } protected override void OnLoadCompleted(AsyncCompletedEventArgs e) { base.OnLoadCompleted(e); } protected override void OnMouseWheel(MouseEventArgs e) { base.OnMouseWheel(e); } protected override void OnKeyDown(KeyEventArgs e) { base.OnKeyDown(e); if (e.KeyCode == Keys.Up) CutImageArea.Location = new Point(CutImageOldLocation.X, CutImageOldLocation.Y + 5); } protected override void OnMouseUp(MouseEventArgs e) { base.OnMouseUp(e); mouseDirection = MouseDirection.NONE; } protected override void OnMouseMove(MouseEventArgs e) { base.OnMouseMove(e); if (mouseDirection != MouseDirection.NONE && mouseDirection != MouseDirection.ALL) { DoResponse(e); return; } // /* N * W E * S * */ Point epoint = e.Location; #region 改变鼠标样式 if (IsInArea(new Point(Lites[0].X + side, Lites[0].Y + side), Lites[4].Location, epoint)) { Cursor = Cursors.SizeAll; } else if (IsInArea(Lites[0].Location, side, side, epoint)) { Cursor = Cursors.SizeNWSE; } else if (IsInArea(Lites[4].Location, side, side, epoint)) { Cursor = Cursors.SizeNWSE; } else if (IsInArea(Lites[1].Location, side, side, epoint)) { Cursor = Cursors.SizeNS; } else if (IsInArea(Lites[5].Location, side, side, epoint)) { Cursor = Cursors.SizeNS; } else if (IsInArea(Lites[2].Location, side, side, epoint)) { Cursor = Cursors.SizeNESW; } else if (IsInArea(Lites[6].Location, side, side, epoint)) { Cursor = Cursors.SizeNESW; } else if (IsInArea(Lites[3].Location, side, side, epoint)) { Cursor = Cursors.SizeWE; } else if (IsInArea(Lites[7].Location, side, side, epoint)) { Cursor = Cursors.SizeWE; } else { Cursor = Cursors.Default; } #endregion //当鼠标左键按下去了 if (e.Button == System.Windows.Forms.MouseButtons.Left) { //在可拖动的区域内 if (IsInArea(new Point(Lites[0].X + side, Lites[0].Y + side), Lites[4].Location, epoint)) { mouseDirection = MouseDirection.ALL; } else if (IsInArea(Lites[0].Location, side, side, epoint))//↖ { mouseDirection = MouseDirection.NW; } else if (IsInArea(Lites[4].Location, side, side, epoint))//↘ { mouseDirection = MouseDirection.SE; } else if (IsInArea(Lites[1].Location, side, side, epoint))//↑ { mouseDirection = MouseDirection.N; } else if (IsInArea(Lites[5].Location, side, side, epoint))//↓ { mouseDirection = MouseDirection.S; } else if (IsInArea(Lites[2].Location, side, side, epoint))//↗ { mouseDirection = MouseDirection.NE; } else if (IsInArea(Lites[6].Location, side, side, epoint))//↙ { mouseDirection = MouseDirection.SW; } else if (IsInArea(Lites[3].Location, side, side, epoint))//→ { mouseDirection = MouseDirection.E; } else if (IsInArea(Lites[7].Location, side, side, epoint))//← { mouseDirection = MouseDirection.W; } else { mouseDirection = MouseDirection.NONE; } if (mouseDirection != MouseDirection.NONE && mouseDirection != MouseDirection.ALL) DoResponse(e); if (mouseDirection == MouseDirection.ALL) { Point l = CutImageOldLocation; Point epointToScreen = PointToScreen(e.Location); l.Offset(epointToScreen.X - MouseDownPointToScreen.X, epointToScreen.Y - MouseDownPointToScreen.Y); CutImageArea.Location = l; // if (CutImageArea.Location.X <= (side / 2 + 1)) CutImageArea.Location = new Point((side / 2) + 1, CutImageArea.Location.Y); if (CutImageArea.Y <= (side / 2 + 1)) CutImageArea.Location = new Point(CutImageArea.Location.X, (side / 2) + 1); if (CutImageArea.Location.X >= Width - CutImageArea.Width - (side / 2 + 1)) CutImageArea.Location = new Point(Width - CutImageArea.Width - (side / 2 + 1), CutImageArea.Location.Y); if (CutImageArea.Location.Y >= Height - CutImageArea.Height - (side / 2 + 1)) CutImageArea.Location = new Point(CutImageArea.Location.X, Height - CutImageArea.Height - (side / 2 + 1)); } Invalidate(); } else if (e.Button == System.Windows.Forms.MouseButtons.Right && ownerDraw) { RectEndPoint = e.Location; CutImageArea = new System.Drawing.Rectangle(RectStartPoint, new System.Drawing.Size(e.X - RectStartPoint.X, e.Y - RectStartPoint.Y)); Invalidate(); } } void DoResponse(MouseEventArgs e) { if (!canResize) return; Point epointToScreen = PointToScreen(e.Location); Point l = CutImageOldLocation; l.Offset(epointToScreen.X - this.MouseDownPointToScreen.X, epointToScreen.Y - this.MouseDownPointToScreen.Y); switch (mouseDirection) { case MouseDirection.N: if (CanMove()) CutImageArea.Location = new Point(CutImageOldLocation.X, l.Y); CutImageArea.Height = OldCutImageAreaSize.Height - (epointToScreen.Y - MouseDownPointToScreen.Y); break; case MouseDirection.S: CutImageArea.Height = OldCutImageAreaSize.Height + (epointToScreen.Y - MouseDownPointToScreen.Y); break; case MouseDirection.W: CutImageArea.Width = OldCutImageAreaSize.Width - (epointToScreen.X - MouseDownPointToScreen.X); if (CanMove()) CutImageArea.Location = new Point(l.X, CutImageOldLocation.Y); break; case MouseDirection.E: CutImageArea.Width = OldCutImageAreaSize.Width + (epointToScreen.X - MouseDownPointToScreen.X); break; case MouseDirection.NE: CutImageArea.Width = OldCutImageAreaSize.Width + (epointToScreen.X - MouseDownPointToScreen.X); CutImageArea.Height = OldCutImageAreaSize.Height - (epointToScreen.Y - MouseDownPointToScreen.Y); if (CanMove()) CutImageArea.Location = new Point(CutImageOldLocation.X, l.Y); break; case MouseDirection.SW: CutImageArea.Width = OldCutImageAreaSize.Width - (epointToScreen.X - MouseDownPointToScreen.X); CutImageArea.Height = OldCutImageAreaSize.Height + (epointToScreen.Y - MouseDownPointToScreen.Y); if (CanMove()) CutImageArea.Location = new Point(l.X, CutImageOldLocation.Y); break; case MouseDirection.NW: CutImageArea.Width = OldCutImageAreaSize.Width - (epointToScreen.X - MouseDownPointToScreen.X); CutImageArea.Height = OldCutImageAreaSize.Height - (epointToScreen.Y - MouseDownPointToScreen.Y); if (CanMove()) CutImageArea.Location = new Point(l.X, l.Y); break; case MouseDirection.SE: CutImageArea.Width = OldCutImageAreaSize.Width + (epointToScreen.X - MouseDownPointToScreen.X); CutImageArea.Height = OldCutImageAreaSize.Height + (epointToScreen.Y - MouseDownPointToScreen.Y); CutImageArea.Location = new Point(CutImageOldLocation.X, CutImageOldLocation.Y); break; case MouseDirection.ALL: break; case MouseDirection.NONE: break; default: break; } if (CutImageArea.Width >= Width) CutImageArea.Width = Width - side - 1; if (CutImageArea.Height >= Height) CutImageArea.Height = Height - side - 1; if (CutImageArea.Width <= MiniWidth) CutImageArea.Width = MiniWidth; if (CutImageArea.Height <= MiniHeight) CutImageArea.Height = MiniHeight; Invalidate(); } protected override void OnMouseDown(MouseEventArgs e) { base.OnMouseDown(e); CutImageOldLocation = CutImageArea.Location; CutImageAreaLocationToScreen = PointToScreen(CutImageArea.Location); MouseDownPoint = e.Location; MouseDownPointToScreen = PointToScreen(e.Location); OldCutImageAreaSize = CutImageArea.Size; if (ownerDraw && e.Button == System.Windows.Forms.MouseButtons.Right) { //右键自己绘制截图框 RectStartPoint = e.Location; } } protected override void OnPaint(PaintEventArgs pe) { base.OnPaint(pe); if (showCutArea) { /* 0 1 2 * 7 3 * 6 5 4 */ //左上角 0 Lites[0] = new Rectangle(CutImageArea.Left - side / 2, CutImageArea.Top - side / 2, side, side); //上中 1 Lites[1] = new Rectangle(CutImageArea.Left + (CutImageArea.Width - side) / 2, CutImageArea.Top - side / 2, side, side); //右上角 2 Lites[2] = new Rectangle(CutImageArea.Width + CutImageArea.Left - side / 2, CutImageArea.Top - side / 2, side, side); //右中 3 Lites[3] = new Rectangle(CutImageArea.Width + CutImageArea.Left - side / 2, CutImageArea.Top + (CutImageArea.Height - side) / 2, side, side); //右下角 4 Lites[4] = new Rectangle(CutImageArea.Width + CutImageArea.Left - side / 2, CutImageArea.Top + CutImageArea.Height - side / 2, side, side); //下中 5 Lites[5] = new Rectangle(CutImageArea.Left + (CutImageArea.Width - side) / 2, CutImageArea.Top + CutImageArea.Height - side / 2, side, side); //下中 6 Lites[6] = new Rectangle(CutImageArea.Left - side / 2, CutImageArea.Top + CutImageArea.Height - side / 2, side, side); //下中 7 Lites[7] = new Rectangle(CutImageArea.Left - side / 2, CutImageArea.Top + (CutImageArea.Height - side) / 2, side, side); Pen pen = new Pen(new SolidBrush(borderColor)); pen.DashStyle = dashStyle; pe.Graphics.DrawRectangle(pen, CutImageArea); pe.Graphics.DrawRectangles(pen, Lites); pe.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; System.Drawing.Color cor = System.Drawing.Color.FromArgb(alpha, borderColor); System.Drawing.SolidBrush bsh = new System.Drawing.SolidBrush(cor); pe.Graphics.FillRectangle(bsh, CutImageArea); } } #endregion #region 自定义事件 public delegate void CuttedImage(Image image); [Description("双击截图后触发的事件")] public event CuttedImage OnCuttedImage; #endregion enum MouseDirection { N, S, W, E, NE, SW, NW, SE, ALL, NONE } public enum AreaAlign { Default, Center, RightCenter, RightTop, LeftCenter, LeftBottom, RightBottom } } }
感谢您的阅读。如果文章对您有用,那么请轻轻点个推荐,以资鼓励。
作者:疯狂蚂蚁
技术交流群:306818375
出处:http://www.cnblogs.com/CrazyAnts/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
作者:疯狂蚂蚁
技术交流群:306818375
出处:http://www.cnblogs.com/CrazyAnts/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。