C# 自由形式的作物选择不需要';我不能正常工作
我做了一个程序,让你做一个随机选择,然后选定的区域保存到一个新的图像,但我有一个问题,它不工作,它应该如何。。。我将在此处发布我的代码,以便您可以查看:C# 自由形式的作物选择不需要';我不能正常工作,c#,C#,我做了一个程序,让你做一个随机选择,然后选定的区域保存到一个新的图像,但我有一个问题,它不工作,它应该如何。。。我将在此处发布我的代码,以便您可以查看: private List<Point> Points = null; private bool Selecting = false; private Bitmap SelectedArea = null; private void pictureBox5_MouseDown(object sender, MouseEventArg
private List<Point> Points = null;
private bool Selecting = false;
private Bitmap SelectedArea = null;
private void pictureBox5_MouseDown(object sender, MouseEventArgs e)
{
Points = new List<Point>();
Selecting = true;
}
private void pictureBox5_MouseMove(object sender, MouseEventArgs e)
{
if (!Selecting) return;
Points.Add(new Point(e.X, e.Y));
pictureBox5.Invalidate();
}
private void pictureBox5_MouseUp(object sender, MouseEventArgs e)
{
Selecting = false;
// Copy the selected area.
SelectedArea = GetSelectedArea(pictureBox5.Image, Color.Transparent, Points);
SelectedArea.Save(@"C:\Users\User\Desktop\Gallery\image" + NumberOfClick.ToString() + "cropped.jpeg", ImageFormat.Jpeg);
string filename = @"C:\Users\User\Desktop\Gallery\image" + NumberOfClick.ToString() + "cropped.jpeg";
if(File.Exists(filename))
{
button1.Visible = true;
pictureBox5.Visible = false;
}
}
private void pictureBox5_Paint(object sender, PaintEventArgs e)
{
if ((Points != null) && (Points.Count > 1))
{
using (Pen dashed_pen = new Pen(Color.Black))
{
dashed_pen.DashPattern = new float[] { 5, 5 };
e.Graphics.DrawLines(Pens.White, Points.ToArray());
e.Graphics.DrawLines(dashed_pen, Points.ToArray());
}
}
}
private Bitmap GetSelectedArea(Image source, Color bg_color, List<Point> points)
{
// Make a new bitmap that has the background
// color except in the selected area.
Bitmap big_bm = new Bitmap(source);
using (Graphics gr = Graphics.FromImage(big_bm))
{
// Set the background color.
gr.Clear(bg_color);
// Make a brush out of the original image.
using (Brush br = new TextureBrush(source))
{
// Fill the selected area with the brush.
gr.FillPolygon(br, points.ToArray());
// Find the bounds of the selected area.
Rectangle source_rect = GetPointListBounds(points);
// Make a bitmap that only holds the selected area.
Bitmap result = new Bitmap(
source_rect.Width, source_rect.Height);
// Copy the selected area to the result bitmap.
using (Graphics result_gr = Graphics.FromImage(result))
{
Rectangle dest_rect = new Rectangle(0, 0,
source_rect.Width, source_rect.Height);
result_gr.DrawImage(big_bm, dest_rect,
source_rect, GraphicsUnit.Pixel);
}
// Return the result.
return result;
}
}
}
private Rectangle GetPointListBounds(List<Point> points)
{
int xmin = points[0].X;
int xmax = xmin;
int ymin = points[0].Y;
int ymax = ymin;
for (int i = 1; i < points.Count; i++)
{
if (xmin > points[i].X) xmin = points[i].X;
if (xmax < points[i].X) xmax = points[i].X;
if (ymin > points[i].Y) ymin = points[i].Y;
if (ymax < points[i].Y) ymax = points[i].Y;
}
return new Rectangle(xmin, ymin, xmax - xmin, ymax - ymin);
}
在pictureBox5中,我正在选择并裁剪图片
缩放图像时,需要计算图像的缩放和偏移 下面是如何做到这一点;这假设
PictureBox
确实处于Zoom
模式,而不是Stretch
模式。如果拉伸,则需要分别计算x和y的缩放
SizeF sp = pictureBox5.ClientSize;
SizeF si = pictureBox5.Image.Size;
float rp = sp.Width / sp.Height; // calculate the ratios of
float ri = si.Width / si.Height; // pbox and image
float zoom = (rp > ri) ? sp.Height / si.Height : sp.Width / si.Width;
float offx = (rp > ri) ? (sp.Width - si.Width * zoom) / 2 : 0;
float offy = (rp <= ri)? (sp.Height - si.Height * zoom) / 2 : 0;
Point offset = Point.Round(new PointF(offx, offy));
这是一个演示,它可以绘制普通(左)图像或放大(中)图像。右边是将GetSelectedArea
位图放置到带有复选框背景的PictureBox
上的结果:
案例1:如果在输入时存储点:在GetSelectedArea
方法中,使用此点列表:
private Bitmap GetSelectedArea(Image source, Color bg_color, List<Point> points)
{
var unzoomedPoints =
points.Select(x => Point.Round((unZoomed(Point.Round(x), zoom, offset))))
.ToList();
// Make a new bitmap that has the background
您可以直接使用列表。您需要将SizeMode设置为Normal而不是Zoom,或者也需要缩放选定的点。是的,它工作正常,但我也需要将图像拉伸到picturebox中。。如何缩放选定的点?该示例会滚动到面板中,或者它实际上会滚动“按钮名称”,这对鼠标滚轮或鼠标拖动有效吗?我将在5分钟后重试。。我不得不做点什么。。这是一个惊喜:D?我实现了你的代码,它显示了一个带有一些按钮的新表单,但当我单击它(而不是按钮)时,按钮消失了,当我尝试用鼠标滚轮滚动时,什么都没有发生。实际上我看到了这是如何工作的。。但是它只工作了一小部分时间,因为它消失了。。
PointF zoomed(Point p1, float zoom, Point offset)
{
return (new PointF(p1.X * zoom + offset.X, p1.Y * zoom + offset.Y));
}
PointF unZoomed(Point p1, float zoom, Point offset)
{
return (new PointF((p1.X - offset.X) / zoom, (p1.Y - offset.Y) / zoom));
}
private Bitmap GetSelectedArea(Image source, Color bg_color, List<Point> points)
{
var unzoomedPoints =
points.Select(x => Point.Round((unZoomed(Point.Round(x), zoom, offset))))
.ToList();
// Make a new bitmap that has the background
Points.Add(unZoomed(e.Location, zoom, offset));