2012-01-23 30 views
1

如果我改變圖像的顏色,然後嘗試調整大小,它只調整原始圖像的大小。爲什麼會發生這種情況,我該如何解決?無法調整更改後的圖像大小? C#WinForms

這裏是我的代碼:

private PrintDocument printDoc = new PrintDocument(); 
private PageSettings pgSettings = new PageSettings(); 
private PrinterSettings prtSettings = new PrinterSettings(); 

Bitmap myBitmapImage;  // image (bitmap) for some background mountains 
Boolean isInvert = false; 
Boolean isLOaded = false; 
Boolean isGrayscale = false; 
Boolean isThreshold = false; 
Boolean isResize = false; 

OpenFileDialog ofd; 
Bitmap bmBack; 

public EditImage() 
{ 
    printDoc.PrintPage += new PrintPageEventHandler(printDoc_PrintPage); 

    InitializeComponent(); 
    this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint | ControlStyles.DoubleBuffer, true); 
} 

private void EditImage_Load(object sender, EventArgs e) 
{ 

} 

private void EditImage_Paint(object sender, PaintEventArgs e) 
{ 
    if (isLOaded == true) 
    { 
     Graphics gWindow; // reference to the graphic surface of this window 
     Graphics gBack;  // reference to in-memory surface 

     bmBack = new Bitmap(Width, Height);  // bitmap for window surface copy 

     gWindow = e.Graphics; // get our current window's surface 
     gBack = Graphics.FromImage(bmBack);  // create surfaces from the bitmaps 

     gBack.DrawImage(myBitmapImage, 0, 0, Width, Height); 

     if (isInvert == true) 
     { 
      InvertBitmap(bmBack); 
     } 
     else if (isGrayscale == true) 
     { 
      GrayscaleBitmap(bmBack); 
     } 
     else if (isThreshold == true) 
     { 
      ThresholdBitmap(bmBack); 
     } 
     else if (isResize == true) 
     { 
      bmBack = resizeImage(bmBack, 10, 100); 
     } 

     gWindow.DrawImage(bmBack, 0, 0); 
    } 
} 
private void toolStripMenuItemLoadImage_Click(object sender, EventArgs e) 
{ 
    using (ofd = new OpenFileDialog()) 
    { 
     ofd.Title = "Load Image"; 

     if (ofd.ShowDialog() == DialogResult.OK) 
     { 
      myBitmapImage = new Bitmap(ofd.FileName); 
      this.Invalidate(); 
     } 
    } 
    isLOaded = true; 
} 


private void GrayscaleBitmap(Bitmap bmp) 
{ 
    Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height); 
    System.Drawing.Imaging.BitmapData bmpData = bmp.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, 
     System.Drawing.Imaging.PixelFormat.Format32bppRgb); 

    IntPtr ptr = bmpData.Scan0; 

    int numPixels = bmpData.Width * bmp.Height; 
    int numBytes = numPixels * 4; 
    byte[] rgbValues = new byte[numBytes]; 

    System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, numBytes); 

    for (int i = 0; i < rgbValues.Length; i += 4) 
    { 
     byte gray = (byte)(.3 * rgbValues[i + 0]); //blue 
     gray += (byte)(.59 * rgbValues[i + 1]); //green 
     gray += (byte)(.11 * rgbValues[i + 2]); //red 

     rgbValues[i + 0] = gray; //blue 
     rgbValues[i + 1] = gray; //green 
     rgbValues[i + 2] = gray; //red 
    } 

    System.Runtime.InteropServices.Marshal.Copy(rgbValues, 0, ptr, numBytes); 

    bmp.UnlockBits(bmpData); 
} 

private Bitmap resizeImage(Bitmap sourceBMP, int width, int height) 
{ 
    Bitmap result = new Bitmap(width, height); 
    using(Graphics g = Graphics.FromImage(result)) 
    g.DrawImage(sourceBMP, 0, 0, width, height); 

    return result; 
} 

我也有應對當用戶點擊一個按鈕,並設置布爾變量爲適當的值,以便它調用正確的方法與方法。圖像DO會改變顏色 - 如預期的那樣..但是當我點擊調整大小時,我希望它調整改變顏色的圖像版本 - 不是原始圖像...

回答

4

這裏有很多錯誤:

resizeImage()

  • 你應該處理圖形的對象,您在這裏創建(包裝在一個使用()語句)
  • 不要從這裏無效,這個功能只是調整圖像大小,在您更改圖像後無效圖像和您的Paint方法繪製現在已經改變的圖像。
  • 如果你不再有任何用處,你應該在返回函數之前考慮處理sourceBMP。

GrayscaleBitmap()

  • 這看起來正確的,但同樣沒有理由在這裏無效。在調用函數中調用此方法後,您應該失效。它更有意義。

EditImage_Paint

  • 你不應該從你的Paint事件中調用這些功能。而且你不應該在每個Paint上創建一個新的Bitmap和一個新的Graphics類。這是比必要的更多的工作。這些函數只應在需要根據用戶輸入更改數據時執行(用戶單擊按鈕以應用灰度效果)。

對於你想做的事情,你最多隻需要2個位圖變量。一個用於存儲原始未修改的位圖,以防讓用戶「重置」它或取消任何效果(大多數效果會導致永久數據丟失,您無法再次使灰度圖像變爲彩色)。另一個存儲被繪製的位圖。每次用戶應用效果時,它都會修改第二個位圖,然後調用invalidate。

您所有的塗料功能應該做的是油漆第二位:

Bitmap originalBitmap; // load from file, do not modify 
Bitmap currentBitmap; // when user clicks an effect, modify this bitmap and then Invalidate afterward 

private void EditImage_Paint(object sender, PaintEventArgs e) 
{ 
    e.Graphics.InterpolationMode = InterpolationMode.HighQualityBicubic; 

    // Draw the currentBitmap centered on the window 
    SizeF clientSize = this.ClientSize; 

    double zoomRatio = Math.Min(
     clientSize.Width/currentBitmap.Width, 
     clientSize.Height/currentBitmap.Height 
    ); 

    SizeF zoomedSize = new SizeF(
     (float)(currentBitmap.Width * zoomRatio), 
     (float)(currentBitmap.Height * zoomRatio) 
    ); 

    PointF imageOffset = new PointF(
     (clientSize.Width - zoomedSize.Width)/2, 
     (clientSize.Height - zoomedSize.Height)/2 
    ); 

    e.Graphics.Clear(Color.White); 
    e.Graphics.DrawImage(currentBitmap, imageOffset.X, imageOffset.Y, zoomedSize.Width, zoomedSize.Height); 
} 

這模仿了中心在控制圖像,並繪製以適合窗口一個簡單的變焦效果。

+0

謝謝,所以我已經做出了你所建議的所有改變......除非我不明白如何修復我的繪畫方法......你能給我一個我將如何做的例子嗎? – BigBug

+0

+1幫助 – BigBug

+0

更新了您可以做的事例。 –