简体   繁体   English

通过单击按钮在平移和裁剪之间切换C#

[英]Switch between Pan and Crop by button click C#

I'm using WinForms. 我正在使用WinForms。 In my form i have a picturebox that has the ability to Pan and crop. 在我的表单中,我有一个可以平移和裁剪的图片框。 The issue with my program is i don't have the ability to switch between crop and pan with a click of a button. 我的程序存在的问题是,我没有单击按钮就可以在作物和平移之间切换的能力。 How can i do this? 我怎样才能做到这一点? I provided my code below. 我在下面提供了我的代码。

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

在此处输入图片说明

A good idea would be to use enums. 一个好主意是使用枚举。 For example, define a State enum as so: 例如,这样定义一个State枚举:

 public enum State
        {
            Pan,
            Crop
        }

and include a field 并包含一个字段

private State currentState;

When you click the Pan or Crop buttons, set currentState as so: 单击“平移”或“裁剪”按钮时,将currentState设置为:

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

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

And in you methods, use the currentState field to specify what they should do 在您的方法中,使用currentState字段指定应执行的操作

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

If I understand what you're trying to do, then you need your method named pictureBox1_MouseDown and the one named pictureBox1_MouseMove to be aware of whether the user is in Pan mode or Crop mode. 如果我了解您要执行的操作,则需要使用名为pictureBox1_MouseDown的方法和名为pictureBox1_MouseMove的方法,以了解用户是处于Pan模式还是Crop模式。 You have started on this idea by defining the variable named _isPanning, but you need to use this data in the methods that I've mentioned. 您已经通过定义名为_isPanning的变量开始了这个想法,但是您需要在我提到的方法中使用此数据。

Hopefully my answer will get you going in the right direction. 希望我的回答能使您朝正确的方向前进。 I hesitate to give a more specific answer because there is more than one way to solve the problem. 我不愿给出更具体的答案,因为有多种方法可以解决问题。

Think carefully about what you want to happen when you click on a button or when you drag the image. 请仔细考虑单击按钮或拖动图像时要发生的情况。 At the moment, your crop button attempts to do two things: set the mode and apply the cropping. 此刻,您的裁剪按钮尝试执行两项操作:设置模式并应用裁剪。

Try separating your modes better. 尝试更好地分离模式。 Your button click handlers should only toggle the mode as suggested by @Leigh and the mouse handlers should either pan or crop depending on the mode. 您的按钮单击处理程序应仅按照@Leigh的建议切换模式,鼠标处理程序应根据模式平移或裁剪。

I haven't tested the contents of your methods so they may require some debugging. 我尚未测试您方法的内容,因此它们可能需要调试。 To make this easier, try to follow some kind of convention when naming your variables: eg private fields start with an underscore, methods and properties start with an uppercase letter, variables within a method start with a lower case letter. 为了简化操作,请在命名变量时遵循某种约定:例如,私有字段以下划线开头,方法和属性以大写字母开头,方法中的变量以小写字母开头。 I've also added some whitespace after your comments because it wasn't immediately clear whether they applied to the line before or the line after. 我还在您的评论后添加了一些空格,因为尚不清楚它们是应用于前一行还是后一行。

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

To make the functionality more obvious to the user, you could replace the buttons with radio buttons or figure out how to make the button corresponding to the current state remain pushed in . 为了使功能对用户更显而易见,您可以将按钮替换为单选按钮,或者弄清楚如何使与当前状态相对应的按钮保持按下状态。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM