之前做一个试卷识别的项目的时候需要预先将各个部分裁剪开然后进行识别,而网上的裁剪函数都是记录鼠标的位置然后进行裁剪
public static Bitmap PartDraw(Image src, Rectangle cutpart)//切割图片
{
Bitmap rectbmp = new Bitmap(cutpart.Width, cutpart.Height, PixelFormat.Format24bppRgb);
using (Graphics g = Graphics.FromImage(rectbmp))
{
g.DrawImage(src, new Rectangle(0, 0, cutpart.Width, cutpart.Height), cutpart, GraphicsUnit.Pixel);
g.Dispose();
}
return rectbmp;
}
但是这样做又带来了一个问题就是如果图片是zoom了的那么鼠标的位置和实际图像的位置就会出现偏移,导致实际截图的位置和你想截图的位置完全不一样。
最后采用了坐标比例换算的方法解决了这个问题。
本方法主要关联四个图片控件的事件
坐标换算的原型函数如下
int originalWidth = this.PicSource.Image.Width;
int originalHeight = this.PicSource.Image.Height;
PropertyInfo rectangleProperty = this.PicSource.GetType().GetProperty("ImageRectangle", BindingFlags.Instance | BindingFlags.NonPublic);
Rectangle rectangle = (Rectangle)rectangleProperty.GetValue(this.PicSource, null);
int currentWidth = rectangle.Width;
int currentHeight = rectangle.Height;
double rate = (double)currentHeight / (double)originalHeight;
int black_left_width = (currentWidth == this.PicSource.Width) ? 0 : (this.PicSource.Width - currentWidth) / 2;
int black_top_height = (currentHeight == this.PicSource.Height) ? 0 : (this.PicSource.Height - currentHeight) / 2;
int zoom_x = e.X - black_left_width;
int zoom_y = e.Y - black_top_height;
double original_x = (double)zoom_x / rate;
double original_y = (double)zoom_y / rate;
可以使用实际坐标来换算得出源坐标
所用到的全局变量如下
bool blnDraw;
Point start; //画框的起始点
Rectangle rect;
Point Pstart; //原图的起始点
Rectangle Orect;//在原图中尺寸
然后为图片控件添加以下事件
private void PicSource_MouseDown(object sender, MouseEventArgs e)
{
int originalWidth = this.PicSource.Image.Width;
int originalHeight = this.PicSource.Image.Height;
PropertyInfo rectangleProperty = this.PicSource.GetType().GetProperty("ImageRectangle", BindingFlags.Instance | BindingFlags.NonPublic);
Rectangle rectangle = (Rectangle)rectangleProperty.GetValue(this.PicSource, null);
int currentWidth = rectangle.Width;
int currentHeight = rectangle.Height;
double rate = (double)currentHeight / (double)originalHeight;
int black_left_width = (currentWidth == this.PicSource.Width) ? 0 : (this.PicSource.Width - currentWidth) / 2;
int black_top_height = (currentHeight == this.PicSource.Height) ? 0 : (this.PicSource.Height - currentHeight) / 2;
int zoom_x = e.X - black_left_width;
int zoom_y = e.Y - black_top_height;
double original_x = (double)zoom_x / rate;
double original_y = (double)zoom_y / rate;
Pstart = new Point((int)original_x, (int)original_y);
start = e.Location;
Invalidate();
blnDraw = true;
}
private void PicSource_MouseMove(object sender, MouseEventArgs e)
{
if (blnDraw)
{
if (e.Button != MouseButtons.Left)//判断是否按下左键
return;
Point tempEndPoint = e.Location; //记录框的位置和大小
rect.Location = new Point(
Math.Min(start.X, tempEndPoint.X),
Math.Min(start.Y, tempEndPoint.Y));
rect.Size = new Size(
Math.Abs(start.X - tempEndPoint.X),
Math.Abs(start.Y - tempEndPoint.Y));
//记录绘制大小
int originalWidth = this.PicSource.Image.Width;
int originalHeight = this.PicSource.Image.Height;
PropertyInfo rectangleProperty = this.PicSource.GetType().GetProperty("ImageRectangle", BindingFlags.Instance | BindingFlags.NonPublic);
Rectangle rectangle = (Rectangle)rectangleProperty.GetValue(this.PicSource, null);
int currentWidth = rectangle.Width;
int currentHeight = rectangle.Height;
double rate = (double)currentHeight / (double)originalHeight;
int black_left_width = (currentWidth == this.PicSource.Width) ? 0 : (this.PicSource.Width - currentWidth) / 2;
int black_top_height = (currentHeight == this.PicSource.Height) ? 0 : (this.PicSource.Height - currentHeight) / 2;
int zoom_x = e.X - black_left_width;
int zoom_y = e.Y - black_top_height;
double original_x = (double)zoom_x / rate;
double original_y = (double)zoom_y / rate;
Orect.Location = new Point(
Math.Min(Pstart.X, (int)original_x),
Math.Min(Pstart.Y, (int)original_y));
Orect.Size = new Size(
Math.Abs(Pstart.X - (int)original_x),
Math.Abs(Pstart.Y - (int)original_y));
PicSource.Invalidate();
}
}
private void PicSource_MouseUp(object sender, MouseEventArgs e)
{
blnDraw = false; //结束绘制
}
private void PicSource_Paint(object sender, PaintEventArgs e)
{
if (blnDraw)
{
if (PicSource.Image != null)
{
if (rect != null && rect.Width > 0 && rect.Height > 0)
{
e.Graphics.DrawRectangle(new Pen(Color.Red, 3), rect);//重新绘制颜色为红色
}
}
}
}
最后效果如图