2015-10-16 82 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已經詳細闡述了他的回答這種做法。 –