2010-02-08 16 views
40

Estoy tratando de rotar un mapa de bits 90 grados con la siguiente función. El problema es que corta parte de la imagen cuando la altura y el ancho no son iguales.C# rotate bitmap 90 degrees

Aviso del returnBitmap width = original.height y su altura = original.width

Puede alguien ayudarme a solucionar este problema o señalar lo que estoy haciendo mal?

private Bitmap rotateImage90(Bitmap b) 
    { 
     Bitmap returnBitmap = new Bitmap(b.Height, b.Width); 
     Graphics g = Graphics.FromImage(returnBitmap); 
     g.TranslateTransform((float)b.Width/2, (float)b.Height/2); 
     g.RotateTransform(90); 
     g.TranslateTransform(-(float)b.Width/2, -(float)b.Height/2); 
     g.DrawImage(b, new Point(0, 0)); 
     return returnBitmap; 
    } 

Respuesta

81

¿Qué hay de this:

private void RotateAndSaveImage(String input, String output) 
{ 
    //create an object that we can use to examine an image file 
    using (Image img = Image.FromFile(input)) 
    { 
     //rotate the picture by 90 degrees and re-save the picture as a Jpeg 
     img.RotateFlip(RotateFlipType.Rotate90FlipNone); 
     img.Save(output, System.Drawing.Imaging.ImageFormat.Jpeg); 
    } 
} 
+0

el mapa de bits que estoy rotación es sólo para fines de visualización. Nunca lo guardo en un archivo – Kevin

+3

; no es necesario que lo guarde; ese 'RotateFlip' hará el truco. Puede eliminar ese 'using' y agregar un' return new Bitmap (img); ' –

+0

Puede que desee obtener un código aquí para asegurarse de que el jpeg se guarde con un nivel de calidad superior al predeterminado 50 http://stackoverflow.com/questions/1484759/quality-of-a-saved-jpg-inc-c-sharp –

8

El error está en su primera llamada a TranslateTransform:

g.TranslateTransform((float)b.Width/2, (float)b.Height/2); 

esta transformación tiene que estar en el espacio de coordenadas returnBitmap en lugar de b, entonces esto debería ser:

g.TranslateTransform((float)b.Height/2, (float)b.Width/2); 

o equivalentemente

g.TranslateTransform((float)returnBitmap.Width/2, (float)returnBitmap.Height/2); 

Su segundo TranslateTransform es correcta, ya que se aplica antes de la rotación.

Sin embargo, es probable que estés mejor con el método más simple RotateFlip, como sugirió Rubens Farias.

1

Me encontré y con una pequeña modificación lo hice funcionar. Encontré algunos otros ejemplos y noté que faltaba algo que marcó la diferencia para mí. Tuve que llamar a SetResolution, si no lo hice, la imagen terminó en un tamaño incorrecto. También noté que la altura y el ancho estaban hacia atrás, aunque de todos modos creo que habría alguna modificación para una imagen no cuadrada. Pensé que publicaría esto para cualquiera que se encuentre con esto como lo hice con el mismo problema.

Aquí está mi código

private static void RotateAndSaveImage(string input, string output, int angle) 
{ 
    //Open the source image and create the bitmap for the rotatated image 
    using (Bitmap sourceImage = new Bitmap(input)) 
    using (Bitmap rotateImage = new Bitmap(sourceImage.Width, sourceImage.Height)) 
    { 
     //Set the resolution for the rotation image 
     rotateImage.SetResolution(sourceImage.HorizontalResolution, sourceImage.VerticalResolution); 
     //Create a graphics object 
     using (Graphics gdi = Graphics.FromImage(rotateImage)) 
     { 
      //Rotate the image 
      gdi.TranslateTransform((float)sourceImage.Width/2, (float)sourceImage.Height/2); 
      gdi.RotateTransform(angle); 
      gdi.TranslateTransform(-(float)sourceImage.Width/2, -(float)sourceImage.Height/2); 
      gdi.DrawImage(sourceImage, new System.Drawing.Point(0, 0)); 
     } 

     //Save to a file 
     rotateImage.Save(output); 
    } 
} 
Cuestiones relacionadas