简体   繁体   中英

Switch between Pan and Crop by button click C#

I'm using 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:

 public enum State
        {
            Pan,
            Crop
        }

and include a field

private State currentState;

When you click the Pan or Crop buttons, set currentState as so:

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

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

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.

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 .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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