【问题标题】:Why can't it draw a rectangle the opposite way?为什么它不能以相反的方式绘制一个矩形?
【发布时间】:2018-07-03 08:41:04
【问题描述】:

所以我正在尝试重新创建 Windows 附带的截图工具。 但是我设法让它从左上角绘制一个矩形,然后当我将光标移动到右下角时。

但是,如果我尝试将光标从屏幕中间移动到左上角,它不会绘制矩形。 为什么是这样? 这是一个 GIF 显示发生了什么

https://i.imgur.com/0Y7xXnS.gifv

//These variables control the mouse position
        int selectX;
        int selectY;
        int selectWidth;
        int selectHeight;
        public Pen selectPen;

        //This variable control when you start the right click
        bool start;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            //Hide the Form
            this.Hide();

            //Create the Bitmap (This is an a black bitmap holding just the size.) (Bitmap is mutable)
            Bitmap printscreen = new Bitmap(Screen.PrimaryScreen.Bounds.Width,
                Screen.PrimaryScreen.Bounds.Height);

            //Create a graphics object that's ready for alteration. `printscreen` is now a graphics Object
            Graphics graphics = Graphics.FromImage(printscreen);

            //Alter the graphics object which again is the printscreen
            graphics.CopyFromScreen(0, 0, 0, 0, printscreen.Size);

            //Create a temporary memory stream for the image
            using (MemoryStream s = new MemoryStream())
            {
                //save graphic variable into memory
                printscreen.Save(s, ImageFormat.Bmp);

                //Set the size of the picturebox
                pictureBox1.Size = new Size(Width, Height);

                //set the value of the picturebox.Image to an Image.FromStream and load the temp stream
                pictureBox1.Image = Image.FromStream(s);
            }
            //Show Form
            this.Show();

            //Cross Cursor
            Cursor = Cursors.Cross;
        }

        private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                selectX = e.X;
                selectY = e.Y;
                selectPen = new Pen(Color.DimGray, 1);
                selectPen.DashStyle = DashStyle.Solid;
                pictureBox1.Refresh();
                start = true;
            }
        }


        private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
        {
            if (start)
            {
                selectWidth = e.X - selectX;
                selectHeight = e.Y - selectY;
                pictureBox1.Refresh();
                pictureBox1.CreateGraphics().DrawRectangle(selectPen,
                    selectX, selectY, selectWidth, selectHeight);
            }
        }

        private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                Stream sound = Resources.SnapshotSound;
                SoundPlayer player = new SoundPlayer(sound);
                player.PlaySync();
                Application.Exit();
            }
        }

【问题讨论】:

  • 你不会得到负的宽度和高度吗?说,向下,x=5,然后移动,x < 5,所以宽度是负数。
  • 这就是我的想法,玩弄并研究 DrawRectangle 的负值
  • 您需要跟踪它们从哪里开始(并将其与鼠标移动时的位置进行比较)以确定“开始”和“当前”是哪个点。

标签: c# .net graphics bitmap


【解决方案1】:

所以你最终得到的基本上是一个具有负宽度和高度的矩形。

您可能希望使用 Math.Abs​​ 来确保在差异变为负数的情况下获得适当的宽度和高度。

这样,您可能还希望根据光标相对于所选点的位置从不同位置进行绘制。类似的东西

            selectWidth = e.X - selectX;
            selectHeight = e.Y - selectY;

            // If width is less than 0, draw from pointer, otherwise from select X
            var drawFromX = selectWidth < 0 ? e.X : selectX;

            // If height is less than 0, draw from pointer, otherwise from select Y
            var drawFromY = selectHeight < 0 ? e.Y : selectY;

            pictureBox1.Refresh();
            pictureBox1.CreateGraphics().DrawRectangle(selectPen,
                drawFromX, 
                drawFromY, 
                Math.Abs(selectWidth),  // Make sure the rectangle width is positive
                Math.Abs(selectHeight)); // Make sure the rectangle height is positive

【讨论】:

  • var drawFromX = Math.Min(e.X, selectX); 呢?
  • 听起来不错 :) 在这样的简单案例中,这只是一个偏好问题。把 cmets 放在里面,使用方法只是个人喜好。
  • 是的 :-)
  • 我忘记了我必须跟踪起点并从那里计算。感谢所有帮助!
猜你喜欢
  • 2011-03-29
  • 1970-01-01
  • 1970-01-01
  • 2014-05-03
  • 2014-11-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多