class MyPictureBox : PictureBox
{
public Point StartPoint { get; set; }
public Point currentPoint { get; set; }
public bool mouseDownSuccess { get; set; }
public Image oriImage { get; set; }
public MyPictureBox()
{
this.SetStyle(ControlStyles.ResizeRedraw, true);//空间大小改变时,控件会重绘
this.SetStyle(ControlStyles.UserPaint, true);
this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
int width = Math.Abs(currentPoint.X - StartPoint.X);
int height = Math.Abs(currentPoint.Y - StartPoint.Y);
Graphics graphics = e.Graphics;
Rectangle rectangle = new Rectangle(StartPoint.X, StartPoint.Y, width, height);
graphics.Clear(Color.FromArgb(255, 240, 240, 240));
graphics.SmoothingMode = SmoothingMode.AntiAlias;//消除锯齿
if (this.Image != null)
{
Rectangle newRectangle = fitInside(new Rectangle(0, 0, this.Width, this.Height), new Size(this.Image.Width, this.Image.Height));//获取图像等比例缩放所需的控件中绘图的区域
graphics.DrawImage(this.Image, newRectangle);
}
Pen pen = new Pen(Color.Red, 2);//指定画笔的颜色和线宽
graphics.DrawRectangle(pen, rectangle);//绘制圆的边界
pen.Dispose();
}
Rectangle fitInside(Rectangle controlRectangle, Size imgSize)
{
int w = controlRectangle.Width;//先以控件宽度作为图像宽度,然后图像高度按照比例缩放
int h = w * imgSize.Height / imgSize.Width;
if (h > controlRectangle.Height)
{
//只能以控件高度作为图像高度了
h = controlRectangle.Height;
w = h * imgSize.Width / imgSize.Height;
}
int startX = controlRectangle.X + (controlRectangle.Width - w) / 2;
int startY = controlRectangle.Y + (controlRectangle.Height - h) / 2;
return new Rectangle(startX, startY, w, h);
}
double[] GetScale(Rectangle controlRectangle, Size imgSize ,ref int scale)
{
int w = controlRectangle.Width;//先以控件宽度作为图像宽度,然后图像高度按照比例缩放
int h = w * imgSize.Height / imgSize.Width;
if (h > controlRectangle.Height)
{
//只能以控件高度作为图像高度了
h = controlRectangle.Height;
w = h * imgSize.Width / imgSize.Height;
scale = imgSize.Height / controlRectangle.Height;
return new double[]{ ((controlRectangle .Width -w)*1.0/ 2),0};//返回截图的起始坐标点需要减去的X、Y
}
else
{
scale = imgSize.Width / controlRectangle.Width;
return new double[] { 0,((controlRectangle.Height - h) * 1.0 / 2), 0 };
}
}
protected override void OnMouseDown(MouseEventArgs e)
{
base.OnMouseDown(e);
if (!mouseDownSuccess)
{
mouseDownSuccess = true;
StartPoint = e.Location;
}
}
protected override void OnMouseMove(MouseEventArgs e)
{
base.OnMouseMove(e);
if (mouseDownSuccess)
{
if (e != null)
{
currentPoint = e.Location;
}
this.Invalidate();//鼠标滑动则强制图面刷新,会触发OnPaint事件
}
}
protected override void OnMouseUp(MouseEventArgs e)
{
base.OnMouseUp(e);
if (mouseDownSuccess)
{
#region 保存截取的图片
int width = Math.Abs(currentPoint.X - StartPoint.X);
int height = Math.Abs(currentPoint.Y - StartPoint.Y);
mouseDownSuccess = false;
System.Drawing.Rectangle rect = new System.Drawing.Rectangle(StartPoint.X, StartPoint.Y, width, height);
if (rect.Width > 0 && rect.Height > 0)
{
if (this.Image != null)
{
int scale = default;
double[] array = GetScale(new Rectangle(0, 0, this.Width, this.Height), new Size(this.Image.Width, this.Image.Height),ref scale );
int centerX = StartPoint.X + width / 2 - Convert.ToInt32(array[0]);//求截图区域中心点X在控件中图像的坐标
int centerY = StartPoint.Y + height / 2 - Convert.ToInt32(array[1]);
int newCenterX = Convert.ToInt32(centerX * scale);//求截图区域中心点X在实际图像的坐标
int newCenterY = Convert.ToInt32(centerY * scale);
int newWidth = Convert.ToInt32(width * scale);//求截图区域在真实图像中的宽度
int newHeight = Convert.ToInt32(height * scale);
int newStartX = newCenterX - newWidth / 2;//求截图区域起始点在实际图像的坐标
int newStartY = newCenterY - newHeight / 2;
rect = new System.Drawing.Rectangle(newStartX, newStartY, newWidth, newHeight);
Bitmap bmp = new Bitmap(this.Image);
Image<Gray, byte> oriImage = new Image<Gray, byte>(bmp);
Image<Gray, byte> dstImage = oriImage.GetSubRect(rect);//获取原始图像指定区域的图像
Image<Gray, byte> CropImage = new Image<Gray, byte>(dstImage.Size);
CvInvoke.cvCopy(dstImage, CropImage, IntPtr.Zero);
CropImage.Save("d:\\1.bmp");
}
}
#endregion
}
}
}