2010-12-01 25 views
1

考慮下面的代碼來旋轉圖像。旋轉圖像修改分辨率和清晰度

問題是圖像的分辨率越來越低,圖像越來越模糊。

我該如何避免這個問題?

private Bitmap rotateImage(Bitmap b, float angle) 
{ 
    //create a new empty bitmap to hold rotated image 
    Bitmap returnBitmap = new Bitmap(b.Width, b.Height); 
    //make a graphics object from the empty bitmap 
    Graphics g = Graphics.FromImage(returnBitmap); 
    //move rotation point to center of image 
    g.TranslateTransform((float)this.Width/2, (float)this.Height/2); 
    g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBilinear; 
    //rotate 
    g.RotateTransform(angle); 
    g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBilinear; 
    g.TranslateTransform(-(float)this.Width/2, -(float)this.Height/2); 
    g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBilinear; 
    //draw passed in image onto graphics object 
    g.DrawImage(b, new Point(0, 0)); 
    g.Dispose(); 
    return returnBitmap; 
} 

回答

4

重複的旋轉將導致質量下降,因爲重複的內插對圖像造成影響。避免這種情況的最好方法是隻旋轉一次源圖像。如果您要構建一個多次旋轉圖像的系統,只需將旋轉源圖像旋轉總旋轉量,而不是每次對已旋轉的圖像應用小的旋轉角度。

+0

他在哪裏說他多次旋轉它?我錯過了什麼嗎? – 2010-12-01 02:07:00

+0

@Brian - 假設對我來說。他目前的代碼不應該在單次輪換中將質量降低到任何可觀的數量。 – Donnie 2010-12-01 02:14:48

3

我有一個方法,我用來做旋轉,它的工作原理沒有顯着降低圖像質量(我見過)。

public static Bitmap RotateImage(Image image, float angle) 
     { 
      if(image == null) 
       throw new ArgumentNullException("image"); 

      const double pi2 = Math.PI/2.0; 


      double oldWidth = (double) image.Width; 
      double oldHeight = (double) image.Height; 

      // Convert degrees to radians 
      double theta = ((double) angle) * Math.PI/180.0; 
      double locked_theta = theta; 

      // Ensure theta is now [0, 2pi) 
      while(locked_theta < 0.0) 
       locked_theta += 2 * Math.PI; 

      double newWidth, newHeight; 
      int nWidth, nHeight; // The newWidth/newHeight expressed as ints 



      double adjacentTop, oppositeTop; 
      double adjacentBottom, oppositeBottom; 


      if((locked_theta >= 0.0 && locked_theta < pi2) || 
       (locked_theta >= Math.PI && locked_theta < (Math.PI + pi2))) 
      { 
       adjacentTop = Math.Abs(Math.Cos(locked_theta)) * oldWidth; 
       oppositeTop = Math.Abs(Math.Sin(locked_theta)) * oldWidth; 

       adjacentBottom = Math.Abs(Math.Cos(locked_theta)) * oldHeight; 
       oppositeBottom = Math.Abs(Math.Sin(locked_theta)) * oldHeight; 
      } 
      else 
      { 
       adjacentTop = Math.Abs(Math.Sin(locked_theta)) * oldHeight; 
       oppositeTop = Math.Abs(Math.Cos(locked_theta)) * oldHeight; 

       adjacentBottom = Math.Abs(Math.Sin(locked_theta)) * oldWidth; 
       oppositeBottom = Math.Abs(Math.Cos(locked_theta)) * oldWidth; 
      } 

      newWidth = adjacentTop + oppositeBottom; 
      newHeight = adjacentBottom + oppositeTop; 

      nWidth = (int) Math.Ceiling(newWidth); 
      nHeight = (int) Math.Ceiling(newHeight); 

      Bitmap rotatedBmp = new Bitmap(nWidth, nHeight); 

      using(Graphics g = Graphics.FromImage(rotatedBmp)) 
      { 

       Point [] points; 

       if(locked_theta >= 0.0 && locked_theta < pi2) 
       { 
        points = new Point[] { 
              new Point((int) oppositeBottom, 0), 
              new Point(nWidth, (int) oppositeTop), 
              new Point(0, (int) adjacentBottom) 
             }; 

       } 
       else if(locked_theta >= pi2 && locked_theta < Math.PI) 
       { 
        points = new Point[] { 
              new Point(nWidth, (int) oppositeTop), 
              new Point((int) adjacentTop, nHeight), 
              new Point((int) oppositeBottom, 0)       
             }; 
       } 
       else if(locked_theta >= Math.PI && locked_theta < (Math.PI + pi2)) 
       { 
        points = new Point[] { 
              new Point((int) adjacentTop, nHeight), 
              new Point(0, (int) adjacentBottom), 
              new Point(nWidth, (int) oppositeTop) 
             }; 
       } 
       else 
       { 
        points = new Point[] { 
              new Point(0, (int) adjacentBottom), 
              new Point((int) oppositeBottom, 0), 
              new Point((int) adjacentTop, nHeight)   
             }; 
       } 

       g.DrawImage(image, points); 
      } 

      return rotatedBmp; 
     } 
1

示例代碼與RotateFlip:

Bitmap bitmap1; 

private void InitializeBitmap() 
{ 
    try 
    { 
     bitmap1 = (Bitmap)Bitmap.FromFile(@"C:\test.bmp"); 
     PictureBox1.SizeMode = PictureBoxSizeMode.AutoSize; 
     PictureBox1.Image = bitmap1; 
    } 
    catch(System.IO.FileNotFoundException) 
    { 
     MessageBox.Show("There was an error." + 
      "Check the path to the bitmap."); 
    } 


} 

private void Button1_Click(System.Object sender, System.EventArgs e) 
{ 

    if (bitmap1 != null) 
    { 
     bitmap1.RotateFlip(RotateFlipType.Rotate180FlipNone); 
     PictureBox1.Image = bitmap1; 
    } 

} 

指定的圖像被多少旋轉,並且所使用的軸線翻轉圖像。 http://msdn.microsoft.com/en-us/library/system.drawing.rotatefliptype.aspx