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 = ;//小框框的大小
private int alpha = ;//遮罩层透明度
private bool showCutArea = true;//是否展示截图框
private Rectangle CutImageArea = new Rectangle(, , , );
private Rectangle[] Lites = new Rectangle[];
private AreaAlign cutAreaAlign = AreaAlign.Default;
private int miniWidth = ;//最小宽
private int miniHeight = ;//最小高
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(, , miniWidth, miniHeight);
break;
case AreaAlign.Center:
CutImageArea = new Rectangle((Width - miniWidth) / , (Height - miniHeight) / , miniWidth, miniHeight);
break;
case AreaAlign.RightCenter:
CutImageArea = new Rectangle(Width - CutImageArea.Width - , (Height - miniHeight) / , miniWidth, miniHeight);
break;
case AreaAlign.RightTop:
CutImageArea = new Rectangle(Width - CutImageArea.Width - , , miniWidth, miniHeight);
break;
case AreaAlign.LeftCenter:
CutImageArea = new Rectangle(, (Height - miniHeight) / , miniWidth, miniHeight);
break;
case AreaAlign.LeftBottom:
CutImageArea = new Rectangle(, Height - CutImageArea.Width - , miniWidth, miniHeight);
break;
case AreaAlign.RightBottom:
CutImageArea = new Rectangle(Width - CutImageArea.Width - , Height - CutImageArea.Width - , 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(, , width, height);
Rectangle sourceRectangle = new Rectangle( + offsetX, + 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[];
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 + );
}
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[].X + side, Lites[].Y + side), Lites[].Location, epoint))
{ Cursor = Cursors.SizeAll; }
else if (IsInArea(Lites[].Location, side, side, epoint))
{ Cursor = Cursors.SizeNWSE; }
else if (IsInArea(Lites[].Location, side, side, epoint))
{ Cursor = Cursors.SizeNWSE; }
else if (IsInArea(Lites[].Location, side, side, epoint))
{ Cursor = Cursors.SizeNS; }
else if (IsInArea(Lites[].Location, side, side, epoint))
{ Cursor = Cursors.SizeNS; }
else if (IsInArea(Lites[].Location, side, side, epoint))
{ Cursor = Cursors.SizeNESW; }
else if (IsInArea(Lites[].Location, side, side, epoint))
{ Cursor = Cursors.SizeNESW; }
else if (IsInArea(Lites[].Location, side, side, epoint))
{ Cursor = Cursors.SizeWE; }
else if (IsInArea(Lites[].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[].X + side, Lites[].Y + side), Lites[].Location, epoint))
{ mouseDirection = MouseDirection.ALL; }
else if (IsInArea(Lites[].Location, side, side, epoint))//↖
{ mouseDirection = MouseDirection.NW; }
else if (IsInArea(Lites[].Location, side, side, epoint))//↘
{ mouseDirection = MouseDirection.SE; }
else if (IsInArea(Lites[].Location, side, side, epoint))//↑
{ mouseDirection = MouseDirection.N; }
else if (IsInArea(Lites[].Location, side, side, epoint))//↓
{ mouseDirection = MouseDirection.S; }
else if (IsInArea(Lites[].Location, side, side, epoint))//↗
{ mouseDirection = MouseDirection.NE; }
else if (IsInArea(Lites[].Location, side, side, epoint))//↙
{ mouseDirection = MouseDirection.SW; }
else if (IsInArea(Lites[].Location, side, side, epoint))//→
{ mouseDirection = MouseDirection.E; }
else if (IsInArea(Lites[].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 / + ))
CutImageArea.Location = new Point((side / ) + , CutImageArea.Location.Y);
if (CutImageArea.Y <= (side / + ))
CutImageArea.Location = new Point(CutImageArea.Location.X, (side / ) + );
if (CutImageArea.Location.X >= Width - CutImageArea.Width - (side / + ))
CutImageArea.Location = new Point(Width - CutImageArea.Width - (side / + ), CutImageArea.Location.Y);
if (CutImageArea.Location.Y >= Height - CutImageArea.Height - (side / + ))
CutImageArea.Location = new Point(CutImageArea.Location.X, Height - CutImageArea.Height - (side / + ));
}
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 - ;
if (CutImageArea.Height >= Height)
CutImageArea.Height = Height - side - ;
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[] = new Rectangle(CutImageArea.Left - side / , CutImageArea.Top - side / , side, side);
//上中 1
Lites[] = new Rectangle(CutImageArea.Left + (CutImageArea.Width - side) / , CutImageArea.Top - side / , side, side);
//右上角 2
Lites[] = new Rectangle(CutImageArea.Width + CutImageArea.Left - side / , CutImageArea.Top - side / , side, side);
//右中 3
Lites[] = new Rectangle(CutImageArea.Width + CutImageArea.Left - side / , CutImageArea.Top + (CutImageArea.Height - side) / , side, side);
//右下角 4
Lites[] = new Rectangle(CutImageArea.Width + CutImageArea.Left - side / , CutImageArea.Top + CutImageArea.Height - side / , side, side);
//下中 5
Lites[] = new Rectangle(CutImageArea.Left + (CutImageArea.Width - side) / , CutImageArea.Top + CutImageArea.Height - side / , side, side);
//下中 6
Lites[] = new Rectangle(CutImageArea.Left - side / , CutImageArea.Top + CutImageArea.Height - side / , side, side);
//下中 7
Lites[] = new Rectangle(CutImageArea.Left - side / , CutImageArea.Top + (CutImageArea.Height - side) / , 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
}
}
}