【问题标题】:Switch between Pan and Crop by button click C#通过按钮单击 C# 在 Pan 和 Crop 之间切换
【发布时间】:2016-01-15 15:13:30
【问题描述】:

我正在使用 WinForms。在我的表单中,我有一个能够平移和裁剪的图片框。我的程序的问题是我无法通过单击按钮在裁剪和平移之间切换。我怎样才能做到这一点?我在下面提供了我的代码。

    //------CROP::::::::::::::
    int cropX;
    int cropY;
    int cropWidth;

    int cropHeight;
    public Pen cropPen;
    //------PAN::::::::::::::::
    private Point _pt;
    private Point _pt2;
    bool _isPanning = false;
    Point startPt;
    //-----Button on/off:::::::
    private bool crop_btn_OFF = false;
    private bool pan_btn_OFF = false;

    private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
    {
        _isPanning = true;
        startPt = e.Location;

        if (e.Button == System.Windows.Forms.MouseButtons.Left )
            {
                Cursor = Cursors.Cross;
                cropX = e.X;
                cropY = e.Y;

                cropPen = new Pen(Color.FromArgb(153, 180, 209), 3);

                cropPen.DashStyle = DashStyle.DashDotDot;
            }
            pictureBox1.Refresh();

    }

    private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
    {
        if (e.Button == System.Windows.Forms.MouseButtons.Left)
        {
            //X and Y are the position of the crop
            pictureBox1.Refresh();
            cropWidth = e.X - cropX;
            cropHeight = e.Y - cropY;
            pictureBox1.CreateGraphics().DrawRectangle(cropPen, cropX, cropY, cropWidth, cropHeight);
        }

        //if (_isPanning) Un-comment this to Pan the image
        //{    
        //    Cursor = Cursors.SizeAll;
        //    Control c = (Control)sender;
        //    c.Left = (c.Left + e.X) - startPt.X;
        //    c.Top = (c.Top + e.Y) - startPt.Y;
        //    c.BringToFront();
        //}
    }

    private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
    {
        _isPanning = false;
        Cursor = Cursors.Default;
    }

    private void btn_Crop_Click(object sender, EventArgs e)
    {

        crop_btn_OFF = true;
        pan_btn_OFF = false;


        if (cropWidth < 1)
        {
            return;
        }
        Rectangle rect = new Rectangle(cropX, cropY, cropWidth, cropHeight);
        //First we define a rectangle with the help of already calculated points
        Bitmap OriginalImage = new Bitmap(pictureBox1.Image, pictureBox1.Width, pictureBox1.Height);
        //Original image
        Bitmap _img = new Bitmap(cropWidth, cropHeight);
        // for cropinf image
        Graphics g = Graphics.FromImage(_img);
        // create graphics
        g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
        g.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;
        g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
        //set image attributes
        g.DrawImage(OriginalImage, 0, 0, rect, GraphicsUnit.Pixel);

        pictureBox1.Image = _img;
        pictureBox1.Width = _img.Width;
        pictureBox1.Height = _img.Height;
    }

    private void btn_Pan_Click(object sender, EventArgs e)
    {
        crop_btn_OFF = false;
        pan_btn_OFF = true;
    }

【问题讨论】:

    标签: c# .net winforms crop pan


    【解决方案1】:

    仔细考虑单击按钮或拖动图像时想要发生的情况。目前,您的裁剪按钮尝试做两件事:设置模式和应用裁剪。

    尝试更好地分离您的模式。您的按钮单击处理程序应仅按照@Leigh 的建议切换模式,并且鼠标处理程序应根据模式进行平移或裁剪。

    我没有测试过你方法的内容,所以它们可能需要一些调试。为了使这更容易,在命名变量时尝试遵循某种约定:例如私有字段以下划线开头,方法和属性以大写字母开头,方法中的变量以小写字母开头。我还在您的 cmets 之后添加了一些空格,因为尚不清楚它们是应用于之前的行还是之后的行。

    private enum State
    {
        Pan,
        Crop
    }
    private State _currentState;
    
    public void btnCrop_Click()
    {
        _currentState = State.Crop;
    }
    
    public void btnPan_Click()
    {
        _currentState = State.Pan;
    }
    
    private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
    {
        if (_currentState == State.Crop)
        {
            if (e.Button == System.Windows.Forms.MouseButtons.Left )
            {
                Cursor = Cursors.Cross;
                _cropX = e.X;
                _cropY = e.Y;
    
                _cropPen = new Pen(Color.FromArgb(153, 180, 209), 3);
    
                _cropPen.DashStyle = DashStyle.DashDotDot;
                pictureBox1.Refresh();
            }
        }
        else // state = pan
        {            
            _isPanning = true;
            _startPt = e.Location;
        }
    }
    
    private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
    {
        if (_currentState == State.Crop)
        {
            Cursor = Cursors.Cross;
            if (e.Button == System.Windows.Forms.MouseButtons.Left)
            {
                //X and Y are the position of the crop
                pictureBox1.Refresh();
                _cropWidth = e.X - _cropX;
                _cropHeight = e.Y - _cropY;
                pictureBox1.CreateGraphics().DrawRectangle(_cropPen, _cropX, _cropY, _cropWidth, _cropHeight);
            }
        }
        else // state = pan
            if (_isPanning)
            {    
                Cursor = Cursors.SizeAll;
                Control c = (Control)sender;
                c.Left = (c.Left + e.X) - _startPt.X;
                c.Top = (c.Top + e.Y) - _startPt.Y;
                c.BringToFront();
            }
        }
    }
    
    private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
    {
        Cursor = Cursors.Default;
        if (_currentState == State.Crop)
        {            
            if (cropWidth < 1)
            {
                return;
            }
    
            Rectangle rect = new Rectangle(_cropX, _cropY, _cropWidth, _cropHeight);
            //First we define a rectangle with the help of already calculated points
    
            Bitmap originalImage = new Bitmap(pictureBox1.Image, pictureBox1.Width, pictureBox1.Height);
            //Original image
    
            Bitmap img = new Bitmap(_cropWidth, _cropHeight);
            // for cropinf image
    
            Graphics g = Graphics.FromImage(img);
            // create graphics
    
            g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
            g.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;
            g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
            //set image attributes
    
            g.DrawImage(originalImage, 0, 0, rect, GraphicsUnit.Pixel);
    
            pictureBox1.Image = img;
            pictureBox1.Width = img.Width;
            pictureBox1.Height = img.Height;
        }
        else // state = pan
        {
            // nothing to do here but leaving it for symmetry with the other methods
        }        
    }
    

    为了使功能对用户更明显,您可以将按钮替换为单选按钮或弄清楚如何使按钮与当前状态remain pushed in相对应。

    【讨论】:

    • 谢谢你,卡尔我学到了我想知道的东西,还有更多。 :) *感谢您一直推送的链接真的很有帮助!
    【解决方案2】:

    一个好主意是使用枚举。例如,这样定义State 枚举:

     public enum State
            {
                Pan,
                Crop
            }
    

    并包含一个字段

    private State currentState;
    

    当您单击 Pan 或 Crop 按钮时,将 currentState 设置为:

    public void btnCrop_Click()
            {
                currentState = State.Crop;
            }
    
     public void btnPan_Click()
            {
                currentState = State.Pan;
            }
    

    在你的方法中,使用 currentState 字段来指定他们应该做什么

    public void Foo()
    {
        if (currentState == State.Pan)
        {
            // Do Pan work
        }
        else if (currentState == State.Crop)
        {
            // Do Crop Work
        }
    }
    

    【讨论】:

    • 我将所有这些代码添加到我的程序中。如果我理解正确,我应该将 if(_isPanning) 放在 currentState ==State.Pan 中,并将 Rectangle rect = new Rectangle(cropX,cropY,cropWith...etc... 放在 currentStante ==State.Crop 中。
    • 基本上,是的,这就是您需要做的。 @Carl 在他的回答中详细阐述了这种方法。
    【解决方案3】:

    如果我理解您要执行的操作,那么您需要名为 pictureBox1_MouseDown 的方法和名为 pictureBox1_MouseMove 的方法来了解用户是处于平移模式还是裁剪模式。您已经通过定义名为 _isPanning 的变量开始了这个想法,但是您需要在我提到的方法中使用这些数据。

    希望我的回答能让你朝着正确的方向前进。我不愿给出更具体的答案,因为解决问题的方法不止一种。

    【讨论】:

    • 看起来_isPanning实际上的意思是“用户正在拖动图像”而不是“平移模式处于活动状态,裁剪模式没有”。你真的想要另一个像@Leigh 建议的状态变量。
    猜你喜欢
    • 1970-01-01
    • 2012-12-19
    • 1970-01-01
    • 2019-01-13
    • 2017-09-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-11
    相关资源
    最近更新 更多