2015-10-16 44 views
0

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

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

enter image description here

回答

1

仔细想想当你点击一个按钮或拖动图像时你想要发生什么。目前,您的裁剪按钮尝试做两件事:设置模式并应用裁剪。

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

我没有测试过的你的方法内容,以便他们可能需要一些调试。为了方便起见,请在命名变量时尝试遵循某种惯例:例如私有字段以下划线开头,方法和属性以大写字母开头,方法内的变量以小写字母开头。我在你的评论之后还加了一些空格,因为不清楚他们是应用到前面的行还是后面的行。

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按钮。

+0

谢谢你卡尔我学会了什么我想知道多一点。:) *和感谢留在链接真正推动有帮助! – taji01

1

如果我理解你想要做什么,那么你就需要你的名为pictureBox1_MouseDown方法和一个名为pictureBox1_MouseMove要注意的用户是否是在全景模式或裁切模式。您已经通过定义名为_isPanning的变量开始了这个想法,但是您需要在我提到的方法中使用这些数据。

希望我的回答将让你在正确的方向前进。我毫不犹豫地给出更具体的答案,因为解决问题的方法不止一种。

+0

它看起来像'_isPanning'实际上是指“用户在拖动图像的过程”,而不是“平移模式被激活,作物模式不是”。你真的想要另一个状态变量,像@Leigh所暗示的那样。 – Carl

2

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

public enum State 
     { 
      Pan, 
      Crop 
     } 

,包括现场

private State currentState; 

当您单击平移或裁剪按钮,将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 
    } 
} 
+0

我将所有这些代码添加到我的程序中。如果我正确理解这一点,我应该把我的if(_isPanning)放置在currentState == State.Pan中,并且在currentStante == State.Crop中放置Rectangle rect = new Rectangle(cropX,cropY,cropWith ...等等。 – taji01

+1

本质上说,是的,这就是你需要做的事。@Carl已经详细阐述了他的回答这种做法。 –