如何根据按钮单击事件剪切绘制的矩形并将其显示在图片框中? [英] How can i cut drawn rectangle and display it in a pictureBox according to button click event?
问题描述
我想要的是,如果我在下次单击该按钮时在图片框中的项目之一上绘制了一个矩形,当我在列表框中单击它们时,它将仅显示我绘制的矩形.
What i want is that if i drawed a rectangle on one of the items in the pictureBox next time i click the button it will display those items when i click on them in the listBox only the rectangles i drawed.
这是我目前尝试过的:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
using DannyGeneral;
using System.Diagnostics;
namespace MinimizeCapture
{
public partial class Form1 : Form
{
Point p1 = new Point(0, 0);
Rectangle recttest;
private Rectangle Rect;
private Rectangle[] rectangles;
private Rectangle RectClone;
private bool btn = false;
private Point RectStartPoint = Point.Empty;
private Point RectEndPoint = Point.Empty;
private Brush selectionBrush = new SolidBrush(Color.Red);
private Pen pen;
private string selectedIndex;
private List<string> drawnItems = new List<string>();
private bool ClearGraphics;
public Form1()
{
InitializeComponent();
var windows = OpenWindowGetter.FindWindowsWithText();
ClearGraphics = false;
this.DoubleBuffered = true;
btn = false;
pen = new Pen(selectionBrush);
buttonSnap.Enabled = false;
backgroundWorker1.RunWorkerAsync();
}
private void buttonSnap_Click(object sender, EventArgs e)
{
ClearGraphics = true;
this.listBoxSnap.Items.Clear();
this.pictureBoxSnap.Image = null;
backgroundWorker1.RunWorkerAsync();
}
private void CutRectangle()
{
for (int i = 0; i < rectangles.Length; i++)
{
if (!rectangles[i].IsEmpty)
{
}
}
}
private void listBoxSnap_SelectedIndexChanged(object sender, EventArgs e)
{
WindowSnap snap = this.listBoxSnap.SelectedItem as WindowSnap;
selectedIndex = this.listBoxSnap.SelectedIndex.ToString();
this.pictureBoxSnap.Image = snap.Image;
for (int i = 0; i < rectangles.Length; i++)
{
if (rectangles[i] != RectClone)
{
ClearGraphics = false;
}
else
{
ClearGraphics = true;
}
}
}
private void checkBoxForceMDI_CheckedChanged(object sender, EventArgs e)
{
WindowSnap.ForceMDICapturing = (sender as CheckBox).Checked;
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
listBoxSnap.Invoke(new MethodInvoker(delegate { this.listBoxSnap.Items.Add("Minimized Windows"); }));
listBoxSnap.Invoke(new MethodInvoker(delegate { this.listBoxSnap.Items.AddRange(WindowSnap.GetAllWindows(true,true).ToArray()); }));
}
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
}
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
rectangles = new Rectangle[listBoxSnap.Items.Count];
buttonSnap.Enabled = true;
}
private void pictureBoxSnap_Paint(object sender, PaintEventArgs e)
{
if (pictureBoxSnap.Image != null)
{
{
if (ClearGraphics == false)
{
if (rectangles[listBoxSnap.SelectedIndex] != Rectangle.Empty)
{
e.Graphics.DrawRectangle(Pens.Firebrick, rectangles[listBoxSnap.SelectedIndex]);
}
if (recttest.Width > 10 && recttest.Height > 10)
e.Graphics.DrawRectangle(Pens.Firebrick, recttest);
}
}
}
}
private void pictureBoxSnap_MouseMove(object sender, MouseEventArgs e)
{
if (btn == true)
{
ClearGraphics = false;
RectEndPoint = e.Location;
int currentindex = listBoxSnap.SelectedIndex;
rectangles[currentindex] = RectClone;
Rect = getRect(RectStartPoint, RectEndPoint);
RectClone = Rect;
pictureBoxSnap.Invalidate();
}
}
private void pictureBoxSnap_MouseDown(object sender, MouseEventArgs e)
{
RectStartPoint = e.Location;
btn = true;
Rect = Rectangle.Empty;
RectClone = Rectangle.Empty;
p1 = e.Location;
}
private void pictureBoxSnap_MouseUp(object sender, MouseEventArgs e)
{
recttest = rectangles[listBoxSnap.SelectedIndex];
ClearGraphics = false;
btn = false;
RectEndPoint = e.Location;
pictureBoxSnap.Invalidate();
int currentindex = listBoxSnap.SelectedIndex;
rectangles[currentindex] = RectClone;
if (e.Location.X > p1.X)
{
recttest.X = p1.X;
recttest.Width = e.Location.X - p1.X;
}
else
{
recttest.X = e.Location.X;
recttest.Width = p1.X - e.Location.X;
}
//Top and Height
if (e.Location.Y > p1.Y)
{
recttest.Y = p1.Y;
recttest.Height = e.Location.Y - p1.Y;
}
else
{
recttest.Y = e.Location.Y;
recttest.Height = p1.Y - e.Location.Y;
}
if (recttest.Width > 10 && recttest.Height > 10)
pictureBoxSnap.Invalidate();
}
Rectangle getRect(Point p1, Point p2)
{
Point p = new Point(Math.Min(p1.X, p2.X), Math.Min(p1.Y, p2.Y));
Size s = new Size(Math.Abs(p1.X - p2.X), Math.Abs(p1.Y - p2.Y));
return new Rectangle(p, s);
}
private void ConfirmRectangle_Click(object sender, EventArgs e)
{
ConfirmRectangle.ForeColor = Color.Red;
ConfirmRectangle.Enabled = false;
StreamWriter w = new StreamWriter(@"c:\temp\Settings.txt", true);
w.WriteLine("Rectangle Location: " + RectClone.Location + " Rectangle Size: " + RectClone.Size + " Selected Index: " + selectedIndex);
textBoxIndex.Text = selectedIndex.ToString();
w.Close();
pictureBoxSnap.Image = CropImage();
}
private Bitmap CropImage()
{
Bitmap pic = pictureBoxSnap.Image as Bitmap;
Bitmap cropped = new Bitmap(recttest.Width, recttest.Height);
using (Graphics g = Graphics.FromImage(cropped))
{
g.DrawImage(pic, new Rectangle(0, 0, recttest.Width, recttest.Height),
recttest, GraphicsUnit.Pixel);
}
return cropped;
}
}
}
对于测试,我调用了矩形变量 recttest.在鼠标向上事件中,我得到了我在列表框中当前所选项目中绘制的矩形.
For the test i called the rectangle variable recttest. In the mouse up event i'm getting the rectangle i drawed in the current selected item in the listBox.
我无法在此处上传图像,但是当我单击 ConfirmRectangle 按钮时,我看到我在图片框中绘制的矩形与原来相同,并且图片框中的图像调整大小后变得非常大里面就像放大一样.
I can't upload here images but what i get is when i click the ConfirmRectangle button i see the the rectangle i drawed in the pictureBox the same as it was and the image in the pictureBox get resize get very very big from the inside like it was zoom in.
相反,我想要的是图片框中由矩形标记/绘制的图像部分.就像矩形是边框一样,所以当我点击 ConfirmRectangle 时,我会看到图像的一部分在矩形的图片框中,只有这部分不应该显示.
Instead what i wanted to get is the part of the image in the pictureBox that was marked/drawed by the rectangle. Like the rectangle is the border so when i click on the ConfirmRectangle i will see the part of the image was in the pictureBox in the rectangle and only this all the rest should not be shown.
我应该在图像的内部看到矩形.不调整大小或放大图像只是为了剪切矩形标记/绘制的部分.
I should see rectangle with inside the part of the image. Not to resize or zoom in the image only to cut the part was marked/drawn on by the rectangle.
推荐答案
试试下面的方法.
Boolean bHaveMouse;
Point ptOriginal = new Point();
Point ptLast = new Point();
private void pictureBox_MouseDown(object sender, MouseEventArgs e)
{
bHaveMouse = true;
// Store the "starting point" for this rubber-band rectangle.
ptOriginal.X = e.X;
ptOriginal.Y = e.Y;
// Special value lets us know that no previous
// rectangle needs to be erased.
ptLast.X = -1;
ptLast.Y = -1;
}
// Convert and normalize the points and draw the reversible frame.
private void MyDrawReversibleRectangle(Point p1, Point p2)
{
Rectangle rc = new Rectangle();
// Convert the points to screen coordinates.
p1 = pictureBox.PointToScreen(p1);
p2 = pictureBox.PointToScreen(p2);
// Normalize the rectangle.
if (p1.X < p2.X)
{
rc.X = p1.X;
rc.Width = p2.X - p1.X;
}
else
{
rc.X = p2.X;
rc.Width = p1.X - p2.X;
}
if (p1.Y < p2.Y)
{
rc.Y = p1.Y;
rc.Height = p2.Y - p1.Y;
}
else
{
rc.Y = p2.Y;
rc.Height = p1.Y - p2.Y;
}
// Draw the reversible frame.
rect = new Rectangle(pictureBox.PointToClient(rc.Location), rc.Size);
ControlPaint.DrawReversibleFrame(rc, Color.Gray, FrameStyle.Dashed);
}
Rectangle rect = Rectangle.Empty;
private void pictureBox_MouseUp(object sender, MouseEventArgs e)
{
// Set internal flag to know we no longer "have the mouse".
bHaveMouse = false;
// If we have drawn previously, draw again in that spot
// to remove the lines.
if (ptLast.X != -1)
{
Point ptCurrent = new Point(e.X, e.Y);
MyDrawReversibleRectangle(ptOriginal, ptLast);
}
// Set flags to know that there is no "previous" line to reverse.
ptLast.X = -1;
ptLast.Y = -1;
ptOriginal.X = -1;
ptOriginal.Y = -1;
pictureBox.Invalidate();
}
private void pictureBox_Paint(object sender, PaintEventArgs e)
{
if (rect.Width > 10 && rect.Height > 10)
{
e.Graphics.DrawRectangle(Pens.Gray, rect);
pictureBox1.Image = CropImage();
}
}
private Bitmap CropImage()
{
Bitmap pic = pictureBox.Image as Bitmap;
Bitmap cropped = new Bitmap(rect.Width, rect.Height);
using (Graphics g = Graphics.FromImage(cropped))
{
g.DrawImage(pic, new Rectangle(0, 0, rect.Width, rect.Height),
rect, GraphicsUnit.Pixel);
}
return cropped;
}
private void pictureBox_MouseMove(object sender, MouseEventArgs e)
{
Point ptCurrent = new Point(e.X, e.Y);
// If we "have the mouse", then we draw our lines.
if (bHaveMouse)
{
// If we have drawn previously, draw again in
// that spot to remove the lines.
if (ptLast.X != -1)
{
MyDrawReversibleRectangle(ptOriginal, ptLast);
}
// Update last point.
ptLast = ptCurrent;
// Draw new lines.
MyDrawReversibleRectangle(ptOriginal, ptCurrent);
}
}
输出
我正在使用 ControPaint.DrawReversibleFrame
方法来绘制橡皮筋.要阅读有关此方法的更多信息,您可以参考此教程
I am using ControPaint.DrawReversibleFrame
method to draw rubber band. To read more about this method u can refere this tutorial
这篇关于如何根据按钮单击事件剪切绘制的矩形并将其显示在图片框中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!