自由形式选择作物C#

时间:2016-11-19 15:48:23

标签: c#

如何在图片框中进行自由格式选择(如在paint或photoshop中),然后裁剪该选项并将其保存到文件夹中? 我已经做了一个矩形裁剪,但我想要那个自由形式的选择..

这是我的矩形裁剪:

Image img;
    bool mouseClicked;
    Point startPoint = new Point();
    Point endPoint = new Point();

    Rectangle rectCropArea;

    private void Button1_Click(System.Object sender, System.EventArgs e)
    {
    }

    private void OnLoad(System.Object sender, System.EventArgs e)
    {
        loadPrimaryImage();
    }

    private void loadPrimaryImage()
    {
        img = Image.FromFile("..\\..\\images.jpg");
        PictureBox1.Image = img;
    }

    private void PicBox_MouseUp(System.Object sender, System.Windows.Forms.MouseEventArgs e)
    {
        mouseClicked = false;
        if ((endPoint.X != -1)) {
            Point currentPoint = new Point(e.X, e.Y);
            Y1.Text = e.X.ToString();
            Y2.Text = e.Y.ToString();
        }

        endPoint.X = -1;
        endPoint.Y = -1;
        startPoint.X = -1;
        startPoint.Y = -1;
    }

    private void PicBox_MouseDown(System.Object sender, System.Windows.Forms.MouseEventArgs e)
    {
        mouseClicked = true;
        startPoint.X = e.X;
        startPoint.Y = e.Y;
        //Display coordinates
        X1.Text = startPoint.X.ToString();
        Y1.Text = startPoint.Y.ToString();

        endPoint.X = -1;
        endPoint.Y = -1;

        rectCropArea = new Rectangle(new Point(e.X, e.Y), new Size());
    }

    private void PicBox_MouseMove(System.Object sender, System.Windows.Forms.MouseEventArgs e)
    {
        Point ptCurrent = new Point(e.X, e.Y);


        if ((mouseClicked)) {
            if ((endPoint.X != -1)) {
                //Display Coordinates
                X1.Text = startPoint.X.ToString();
                Y1.Text = startPoint.Y.ToString();
                X2.Text = e.X.ToString();
                Y2.Text = e.Y.ToString();
            }

            endPoint = ptCurrent;

            if ((e.X > startPoint.X & e.Y > startPoint.Y)) {
                rectCropArea.Width = e.X - startPoint.X;
                rectCropArea.Height = e.Y - startPoint.Y;


            } else if ((e.X < startPoint.X & e.Y > startPoint.Y)) {
                rectCropArea.Width = startPoint.X - e.X;
                rectCropArea.Height = e.Y - startPoint.Y;
                rectCropArea.X = e.X;
                rectCropArea.Y = startPoint.Y;

            } else if ((e.X > startPoint.X & e.Y < startPoint.Y)) {
                rectCropArea.Width = e.X - startPoint.X;
                rectCropArea.Height = startPoint.Y - e.Y;
                rectCropArea.X = startPoint.X;
                rectCropArea.Y = e.Y;

            } else {
                rectCropArea.Width = startPoint.X - e.X;
                rectCropArea.Height = startPoint.Y - e.Y;
                rectCropArea.X = e.X;
                rectCropArea.Y = e.Y;
            }

            PictureBox1.Refresh();

        }

    }

    private void PicBox_Paint(System.Object sender, System.Windows.Forms.PaintEventArgs e)
    {
        Pen drawLine = new Pen(Color.Red);
        drawLine.DashStyle = DashStyle.Dash;
        e.Graphics.DrawRectangle(drawLine, rectCropArea);
    }

    private void btnCrop_Click(System.Object sender, System.EventArgs e)
    {
        PictureBox2.Refresh();

        Bitmap sourceBitmap = new Bitmap(PictureBox1.Image, PictureBox1.Width, PictureBox1.Height);
        Graphics g = PictureBox2.CreateGraphics();

        if (!(CheckBox1.Checked)) {
            g.DrawImage(sourceBitmap, new Rectangle(0, 0, PictureBox2.Width, PictureBox2.Height), rectCropArea, GraphicsUnit.Pixel);
            sourceBitmap.Dispose();

        } else {
            int x1 = 0;
            int x2 = 0;
            int y1 = 0;
            int y2 = 0;
            try {
                x1 = Convert.ToInt32(CX1.Text);
                x2 = Convert.ToInt32(CX2.Text);
                y1 = Convert.ToInt32(CY1.Text);
                y2 = Convert.ToInt32(CY2.Text);
            } catch (Exception ex) {
                MessageBox.Show("Enter valid Coordinates (only Integer values)");
            }

            if (((x1 < x2 & y1 < y2))) {
                rectCropArea = new Rectangle(x1, y1, x2 - x1, y2 - y1);
            } else if ((x2 < x1 & y2 > y1)) {
                rectCropArea = new Rectangle(x2, y1, x1 - x2, y2 - y1);
            } else if ((x2 > x1 & y2 < y1)) {
                rectCropArea = new Rectangle(x1, y2, x2 - x1, y1 - y2);
            } else {
                rectCropArea = new Rectangle(x2, y2, x1 - x2, y1 - y2);
            }

            PictureBox1.Refresh();
            //This repositions the dashed box to new location as per coordinates entered.

            g.DrawImage(sourceBitmap, new Rectangle(0, 0, PictureBox2.Width, PictureBox2.Height), rectCropArea, GraphicsUnit.Pixel);
            sourceBitmap.Dispose();
        }
    }

    private void pictureBox1_MouseClick(System.Object sender, System.Windows.Forms.MouseEventArgs e)
    {
        PictureBox1.Refresh();
    }

    private void CheckBox1_CheckedChanged(System.Object sender, System.EventArgs e)
    {
        if ((CheckBox1.Checked)) {
            CX1.Visible = true;
            Label10.Visible = true;
            CY1.Visible = true;
            Label9.Visible = true;
            CX2.Visible = true;
            Label8.Visible = true;
            CY2.Visible = true;
            Label7.Visible = true;

            X1.Text = "0";
            X2.Text = "0";
            Y1.Text = "0";
            Y2.Text = "0";

        } else {
            CX1.Visible = false;
            Label10.Visible = false;
            CY1.Visible = false;
            Label9.Visible = false;
            CX2.Visible = false;
            Label8.Visible = false;
            CY2.Visible = false;
            Label7.Visible = false;
        }

    }
    public Form1()
    {
        Load += OnLoad;
    }
}

1 个答案:

答案 0 :(得分:0)

要复制自由格式选择,您需要使用多边形。

这是一个完整的例子。只需将其粘贴到一个新的解决方案中并尝试一下(只需更改图像的路径)。 它将创建2个图片框并将图像加载到第一个图片框中并创建图像。然后你可以点击第一张图片,当你点击2次后它会开始显示一个选择,当你完成后只需按下按钮,它就会将选择复制到另一个图片框,然后将其保存为png图像。

它的作用是从第一个图像创建一个画笔,然后将多边形绘制到另一个图像上,并将矩形中的其他像素设置为您选择的背景颜色,在本例中为颜色:Color.Transparent。 / p>

示例:

public partial class Form1 : Form {
    private List<Point> _points = new List<Point>();
    private PictureBox _pictureBox1;
    private PictureBox _pictureBox2;
    private Button _button1;
    public Form1() {
        InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e) {
        Size = new Size(1366, 675);

        _pictureBox1 = new PictureBox {
            Location = new Point(12, 51),
            Size = new Size(651, 474),
            BorderStyle = BorderStyle.FixedSingle
        };
        _pictureBox2 = new PictureBox
        {
            Location = new Point(669, 51),
            Size = new Size(651, 474),
            BorderStyle = BorderStyle.FixedSingle
        };
        _button1 = new Button {
            Text = @"Copy selected area",
            Location = new Point(13, 13),
            Size = new Size(175, 23)
        };
        Controls.AddRange(new Control[] { _pictureBox1, _pictureBox2, _button1 });

        _pictureBox1.Image = Image.FromFile(@"d:\temp\Hopetoun_falls.jpg");
        _points = new List<Point>();

        _pictureBox1.MouseDown += delegate(object o, MouseEventArgs args) { _points.Add(args.Location); _pictureBox1.Refresh(); };
        _pictureBox1.Paint += pictureBox1_Paint;

        _button1.Click += button_Click;
    }

    private void pictureBox1_Paint(object sender, PaintEventArgs e) {
        if (_points.Count < 2) {
            return;
        }

        var max = _points.Count;
        for (int i = 1; i < max; i++) {
            e.Graphics.DrawLine(Pens.Red, _points[i-1].X, _points[i-1].Y, _points[i].X, _points[i].Y);
        }
        e.Graphics.DrawLine(Pens.Red, _points[max - 1].X, _points[max - 1].Y, _points[0].X, _points[0].Y);
    }

    private static Bitmap GetSelectedArea(Image source, Color bgColor, List<Point> points) {
        var bigBm = new Bitmap(source);
        using (var gr = Graphics.FromImage(bigBm)) {
            // Set the background color.
            gr.Clear(bgColor);

            // Make a brush out of the original image.
            using (var br = new TextureBrush(source)) {
                // Fill the selected area with the brush.
                gr.FillPolygon(br, points.ToArray());

                // Find the bounds of the selected area.
                var sourceRect = GetPointListBounds(points);

                // Make a bitmap that only holds the selected area.
                var result = new Bitmap(sourceRect.Width, sourceRect.Height);

                // Copy the selected area to the result bitmap.
                using (var resultGr = Graphics.FromImage(result)) {
                    var destRect = new Rectangle(0, 0, sourceRect.Width, sourceRect.Height);
                    resultGr.DrawImage(bigBm, destRect, sourceRect, GraphicsUnit.Pixel);
                }

                // Return the result.
                return result;
            }
        }
    }

    private static 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);
    }
    private void button_Click(object sender, EventArgs e) {
        if (_points.Count < 3) {
            return;
        }

        var img = GetSelectedArea(_pictureBox1.Image, Color.Transparent, _points);
        _pictureBox2.Image = img;
        _pictureBox2.Image.Save(@"d:\temp\sample.png", ImageFormat.Png);
    }
}