Cristi Cretan Ответов: 2

В свободной форме выделения с#


Здравствуйте, я работаю над этим проектом, который мне нужно обрезать из picturebox выбор свободной формы, а затем сохранить новое изображение.

У меня есть этот код, который сохраняет мои загруженные фотографии в папку, которая, если ее не существует, создает ее.

private void button1_Click(object sender, EventArgs e)
        {

            ++NumberOfClick;
            switch (NumberOfClick)
            {
                case 1:
                    OpenFileDialog f = new OpenFileDialog();
                    f.Filter = "Image files (*.jpg, *.jpeg, *.jpe, *.jfif, *.png) | *.jpg; *.jpeg; *.jpe; *.jfif; *.png";

                    if (f.ShowDialog() == DialogResult.OK)
                    {
                        File = Image.FromFile(f.FileName);
                        pictureBox1.Image = File;
                    }

                    pictureBox1.Image.Save(@"C:\Users\User\Desktop\Gallery\image1.png", ImageFormat.Png);

                    DialogResult result = MessageBox.Show("Do you want to crop this image?", "Confirmation", MessageBoxButtons.YesNo);

                    if(result == DialogResult.Yes)
                    {
                        
                        pictureBox5.Visible = true;
                        button1.Visible = false;
                        pictureBox5.Image = pictureBox1.Image;

                    }

                    

                    break;
                case 2:
                    OpenFileDialog f2 = new OpenFileDialog();
                    f2.Filter = "Image files (*.jpg, *.jpeg, *.jpe, *.jfif, *.png) | *.jpg; *.jpeg; *.jpe; *.jfif; *.png";

                    if (f2.ShowDialog() == DialogResult.OK)
                    {
                        File = Image.FromFile(f2.FileName);
                        pictureBox2.Image = pictureBox1.Image;
                        pictureBox1.Image = File;
                    }

                    pictureBox1.Image.Save(@"C:\Users\User\Desktop\Gallery\image2.png", ImageFormat.Png);

                    break;
                case 3:
                    OpenFileDialog f3 = new OpenFileDialog();
                    f3.Filter = "Image files (*.jpg, *.jpeg, *.jpe, *.jfif, *.png) | *.jpg; *.jpeg; *.jpe; *.jfif; *.png";

                    if (f3.ShowDialog() == DialogResult.OK)
                    {
                        File = Image.FromFile(f3.FileName);
                        pictureBox3.Image = pictureBox2.Image;
                        pictureBox2.Image = pictureBox1.Image;
                        pictureBox1.Image = File;
                    }

                    pictureBox1.Image.Save(@"C:\Users\User\Desktop\Gallery\image3.png", ImageFormat.Png);

                    break;
                case 4:
                    OpenFileDialog f4 = new OpenFileDialog();
                    f4.Filter = "Image files (*.jpg, *.jpeg, *.jpe, *.jfif, *.png) | *.jpg; *.jpeg; *.jpe; *.jfif; *.png";

                    if (f4.ShowDialog() == DialogResult.OK)
                    {
                        File = Image.FromFile(f4.FileName);
                        pictureBox4.Image = pictureBox3.Image;
                        pictureBox3.Image = pictureBox2.Image;
                        pictureBox2.Image = pictureBox1.Image;
                        pictureBox1.Image = File;
                    }

                    pictureBox1.Image.Save(@"C:\Users\User\Desktop\Gallery\image4.png", ImageFormat.Png);

                    break;
                default:

                    OpenFileDialog f5 = new OpenFileDialog();
                    f5.Filter = "Image files (*.jpg, *.jpeg, *.jpe, *.jfif, *.png) | *.jpg; *.jpeg; *.jpe; *.jfif; *.png";

                    if (f5.ShowDialog() == DialogResult.OK)
                    {
                        File = Image.FromFile(f5.FileName);

                        File.Save(@"C:\Users\User\Desktop\Gallery\image" + NumberOfClick.ToString() + ".png", ImageFormat.Png);
                        
                        pictureBox4.Image = pictureBox3.Image;
                        pictureBox3.Image = pictureBox2.Image;
                        pictureBox2.Image = pictureBox1.Image;
                        pictureBox1.Image = File;
                    }

                        break;
            }
        }


Что я уже пробовал:

Я уже сделал прямоугольную обрезку, но мне нужен этот выбор свободной формы..

Вот мой прямоугольник обрезки:


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;
	}
}

OriginalGriff

И что же?
Где ты застрял?
Какая помощь вам нужна?

Cristi Cretan

Я понятия не имею, как сделать пользовательский выбор на picturebox... или как обрезать изображение по нему

Richard MacCutchan

Затем вы должны использовать Google, чтобы провести некоторое исследование инструментов, которые вам помогут.

Cristi Cretan

Я сделал. Я ищу часы, но ничего мне не помогает.

2 Ответов

Рейтинг:
2

Dave Kreskowiak

Я могу сказать вам, что ваш код утекает ресурсы. Вы не избавляетесь от ресурса, который создаете, как та ручка, которую вы создаете при каждом обновлении.

Кроме того, вы используете PictureBoxes повсюду. это, вероятно, самые бесполезные и мешающие элементы управления в наборе инструментов, особенно если они настроены на автоматическое масштабирование вашего изображения. Он сделает это без вашего ведома, потому что он не сообщает, когда он это делает.

PictureBox отлично подходит для ситуаций quick'n'Dirty "show this image", когда вы действительно не заботитесь ни о чем другом. Для выбора и редактирования изображений это действительно мешает.

В вашем примере весь ваш код "выбора" для изображения должен быть помещен в свой собственный класс, который наследуется от другого элемента управления, например Panel. Вы получаете возможность самостоятельно нарисовать исходное изображение в нужном вам масштабе и сохранить все значения масштабирования, которые вы можете использовать в своем коде выбора, чтобы получить лучшие результаты для вычисления координат.


Рейтинг:
1

Richard MacCutchan

Вы не можете изучать продвинутый предмет, такой как редактирование изображений, публикуя вопросы на таком форуме, как этот. Вам нужно изучить учебные пособия и видео или купить книгу. Видеть редактирование изображений c-поиск в Google[^].