首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >绘制可逆矩形

绘制可逆矩形
EN

Stack Overflow用户
提问于 2011-02-04 15:32:36
回答 1查看 5.3K关注 0票数 3

我从http://support.microsoft.com/kb/314945获得了绘制可逆/橡皮筋矩形的代码。我给它添加了代码,这样当我离开鼠标左键时,图像上也会创建一个矩形,然后我就可以用它来裁剪图像。

这个很好用。唯一的问题是橡皮筋矩形不会从鼠标所在的位置开始或结束。虽然分歧很小,但仍然相当值得注意。之后,我使用相同的坐标来绘制矩形,该矩形将精确地绘制在鼠标开始和结束的位置。如果能帮上忙,我们将不胜感激。

以下是代码:(Got问题修复-添加代码,以便其他人可以从中受益)我已经使它成为一个控件,我在任何需要它的地方使用它!

代码语言:javascript
复制
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace CroppingControl
{
    public partial class CroppingImage : UserControl
    {
        Rectangle rc = new Rectangle();
        Boolean bHaveMouse;
        Point ptOriginal = new Point();
        Point ptLast = new Point();
        Image Pic;

        public CroppingImage()
        {
            InitializeComponent();
            pictureBox1.MouseDown += new MouseEventHandler(MyMouseDown);
            pictureBox1.MouseUp += new MouseEventHandler(MyMouseUp);
            pictureBox1.MouseMove += new MouseEventHandler(MyMouseMove);
            bHaveMouse = false;
        }


        public Image Image
        {
            set
            {
                pictureBox1.Image = value;
                Pic = value;
            }
            get
            {
                return pictureBox1.Image;
            }
        }

        public void MyMouseDown(Object sender, MouseEventArgs e)
        {
            pictureBox1.Image = Pic;
            // Make a note that we "have the mouse".

            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)
        {
            Point px = p1;
            Point py = p2;

            // Convert the points to screen coordinates.
            p1 = PointToScreen(p1);
            p2 = 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.
            ControlPaint.DrawReversibleFrame(rc, Color.Black, FrameStyle.Dashed);

            rc.X = px.X;
            rc.Y = px.Y;

        }
        // Called when the left mouse button is released.
        public void MyMouseUp(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);
                Graphics graphics = pictureBox1.CreateGraphics();
                Pen pen = new Pen(Color.Gray, 2);
                pen.DashStyle = System.Drawing.Drawing2D.DashStyle.DashDot;
                graphics.DrawRectangle(pen, rc);

            }
            // Set flags to know that there is no "previous" line to reverse.
            ptLast.X = -1;
            ptLast.Y = -1;
            ptOriginal.X = -1;
            ptOriginal.Y = -1;
        }
        // Called when the mouse is moved.
        public void MyMouseMove(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);
            }
        }

    }
}
EN

回答 1

Stack Overflow用户

发布于 2011-02-04 19:56:02

ControlPaint.DrawReversibleFrame使用屏幕坐标在屏幕上绘制一个矩形(即,与应用程序的窗口无关),这在执行拖动鼠标操作时非常有用,因为鼠标可能会移动到应用程序窗口之外。如果您在应用程序中使用相同的坐标raw进行绘制,那么它们将作为您要在其上绘制的控件上的坐标相对于控件的原点(通常是控件的左上角)而存在。

要使用屏幕坐标,首先需要在要绘制的控件上使用PointToClient()RectangleToClient()方法将它们转换为控件坐标,例如

代码语言:javascript
复制
// panel`s OnPaint
Rectangle screenRectangle = ...
Rectangle clientRectangle = panel.RectangleToClient(screenRectangle);
graphics.DrawRectangle(Pens.Red, clientRectangle);
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4895595

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档