visual rotate rotar picture linea imagen girar como c# winforms image

c# - rotate - Cómo rotar una imagen en WinForms



rotar linea c# (10)

Aquí hay un método que puede usar para rotar una imagen en C #:

/// <summary> /// method to rotate an image either clockwise or counter-clockwise /// </summary> /// <param name="img">the image to be rotated</param> /// <param name="rotationAngle">the angle (in degrees). /// NOTE: /// Positive values will rotate clockwise /// negative values will rotate counter-clockwise /// </param> /// <returns></returns> public static Image RotateImage(Image img, float rotationAngle) { //create an empty Bitmap image Bitmap bmp = new Bitmap(img.Width, img.Height); //turn the Bitmap into a Graphics object Graphics gfx = Graphics.FromImage(bmp); //now we set the rotation point to the center of our image gfx.TranslateTransform((float)bmp.Width / 2, (float)bmp.Height / 2); //now rotate the image gfx.RotateTransform(rotationAngle); gfx.TranslateTransform(-(float)bmp.Width / 2, -(float)bmp.Height / 2); //set the InterpolationMode to HighQualityBicubic so to ensure a high //quality image once it is transformed to the specified size gfx.InterpolationMode = InterpolationMode.HighQualityBicubic; //now draw our new image onto the graphics object gfx.DrawImage(img, new Point(0, 0)); //dispose of our Graphics object gfx.Dispose(); //return the image return bmp; }

Quiero tener una imagen en mi aplicación que pueda rotar para indicar direcciones, como la dirección del viento. O incluso el tiempo. ¿Qué código utilizo para rotar la imagen? Gracias

Actualización: estoy usando .NET 2.0, Windows 2000, VS C # 2005


Encontré este article

/// <summary> /// Creates a new Image containing the same image only rotated /// </summary> /// <param name=""image"">The <see cref=""System.Drawing.Image"/"> to rotate /// <param name=""offset"">The position to rotate from. /// <param name=""angle"">The amount to rotate the image, clockwise, in degrees /// <returns>A new <see cref=""System.Drawing.Bitmap"/"> of the same size rotated.</see> /// <exception cref=""System.ArgumentNullException"">Thrown if <see cref=""image"/"> /// is null.</see> public static Bitmap RotateImage(Image image, PointF offset, float angle) { if (image == null) throw new ArgumentNullException("image"); //create a new empty bitmap to hold rotated image Bitmap rotatedBmp = new Bitmap(image.Width, image.Height); rotatedBmp.SetResolution(image.HorizontalResolution, image.VerticalResolution); //make a graphics object from the empty bitmap Graphics g = Graphics.FromImage(rotatedBmp); //Put the rotation point in the center of the image g.TranslateTransform(offset.X, offset.Y); //rotate the image g.RotateTransform(angle); //move the image back g.TranslateTransform(-offset.X, -offset.Y); //draw passed in image onto graphics object g.DrawImage(image, new PointF(0, 0)); return rotatedBmp; }


Escribí una clase simple para rotar la imagen. Todo lo que tienes que hacer es ingresar la imagen y el ángulo de rotación en Grado. El ángulo debe estar entre -90 y +90.

public class ImageRotator { private readonly Bitmap image; public Image OriginalImage { get { return image; } } private ImageRotator(Bitmap image) { this.image = image; } private double GetRadian(double degree) { return degree * Math.PI / (double)180; } private Size CalculateSize(double angle) { double radAngle = GetRadian(angle); int width = (int)(image.Width * Math.Cos(radAngle) + image.Height * Math.Sin(radAngle)); int height = (int)(image.Height * Math.Cos(radAngle) + image.Width * Math.Sin(radAngle)); return new Size(width, height); } private PointF GetTopCoordinate(double radAngle) { Bitmap image = CurrentlyViewedMappedImage.BitmapImage; double topX = 0; double topY = 0; if (radAngle > 0) { topX = image.Height * Math.Sin(radAngle); } if (radAngle < 0) { topY = image.Width * Math.Sin(-radAngle); } return new PointF((float)topX, (float)topY); } public Bitmap RotateImage(double angle) { SizeF size = CalculateSize(radAngle); Bitmap rotatedBmp = new Bitmap((int)size.Width, (int)size.Height); Graphics g = Graphics.FromImage(rotatedBmp); g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic; g.CompositingQuality = CompositingQuality.HighQuality; g.SmoothingMode = SmoothingMode.HighQuality; g.PixelOffsetMode = PixelOffsetMode.HighQuality; g.TranslateTransform(topPoint.X, topPoint.Y); g.RotateTransform(GetDegree(radAngle)); g.DrawImage(image, new RectangleF(0, 0, size.Width, size.Height)); g.Dispose(); return rotatedBmp; } public static class Builder { public static ImageRotator CreateInstance(Image image) { ImageRotator rotator = new ImageRotator(image as Bitmap); return rotator; } } }


Este es un hilo antiguo, y hay varios otros hilos sobre la rotación de imágenes de C # WinForms, pero ahora que he encontrado mi solución, creo que este es un buen lugar para publicarlo como cualquier otro.

/// <summary> /// Method to rotate an Image object. The result can be one of three cases: /// - upsizeOk = true: output image will be larger than the input, and no clipping occurs /// - upsizeOk = false & clipOk = true: output same size as input, clipping occurs /// - upsizeOk = false & clipOk = false: output same size as input, image reduced, no clipping /// /// A background color must be specified, and this color will fill the edges that are not /// occupied by the rotated image. If color = transparent the output image will be 32-bit, /// otherwise the output image will be 24-bit. /// /// Note that this method always returns a new Bitmap object, even if rotation is zero - in /// which case the returned object is a clone of the input object. /// </summary> /// <param name="inputImage">input Image object, is not modified</param> /// <param name="angleDegrees">angle of rotation, in degrees</param> /// <param name="upsizeOk">see comments above</param> /// <param name="clipOk">see comments above, not used if upsizeOk = true</param> /// <param name="backgroundColor">color to fill exposed parts of the background</param> /// <returns>new Bitmap object, may be larger than input image</returns> public static Bitmap RotateImage(Image inputImage, float angleDegrees, bool upsizeOk, bool clipOk, Color backgroundColor) { // Test for zero rotation and return a clone of the input image if (angleDegrees == 0f) return (Bitmap)inputImage.Clone(); // Set up old and new image dimensions, assuming upsizing not wanted and clipping OK int oldWidth = inputImage.Width; int oldHeight = inputImage.Height; int newWidth = oldWidth; int newHeight = oldHeight; float scaleFactor = 1f; // If upsizing wanted or clipping not OK calculate the size of the resulting bitmap if (upsizeOk || !clipOk) { double angleRadians = angleDegrees * Math.PI / 180d; double cos = Math.Abs(Math.Cos(angleRadians)); double sin = Math.Abs(Math.Sin(angleRadians)); newWidth = (int)Math.Round(oldWidth * cos + oldHeight * sin); newHeight = (int)Math.Round(oldWidth * sin + oldHeight * cos); } // If upsizing not wanted and clipping not OK need a scaling factor if (!upsizeOk && !clipOk) { scaleFactor = Math.Min((float)oldWidth / newWidth, (float)oldHeight / newHeight); newWidth = oldWidth; newHeight = oldHeight; } // Create the new bitmap object. If background color is transparent it must be 32-bit, // otherwise 24-bit is good enough. Bitmap newBitmap = new Bitmap(newWidth, newHeight, backgroundColor == Color.Transparent ? PixelFormat.Format32bppArgb : PixelFormat.Format24bppRgb); newBitmap.SetResolution(inputImage.HorizontalResolution, inputImage.VerticalResolution); // Create the Graphics object that does the work using (Graphics graphicsObject = Graphics.FromImage(newBitmap)) { graphicsObject.InterpolationMode = InterpolationMode.HighQualityBicubic; graphicsObject.PixelOffsetMode = PixelOffsetMode.HighQuality; graphicsObject.SmoothingMode = SmoothingMode.HighQuality; // Fill in the specified background color if necessary if (backgroundColor != Color.Transparent) graphicsObject.Clear(backgroundColor); // Set up the built-in transformation matrix to do the rotation and maybe scaling graphicsObject.TranslateTransform(newWidth / 2f, newHeight / 2f); if (scaleFactor != 1f) graphicsObject.ScaleTransform(scaleFactor, scaleFactor); graphicsObject.RotateTransform(angleDegrees); graphicsObject.TranslateTransform(-oldWidth / 2f, -oldHeight / 2f); // Draw the result graphicsObject.DrawImage(inputImage, 0, 0); } return newBitmap; }

Este es el resultado de muchas fuentes de inspiración, aquí en y en otros lugares. La respuesta de Naveen en este hilo fue especialmente útil.


Esto funcionará siempre que la imagen que desea rotar ya se encuentre en la carpeta de recursos de Propiedades.

En clase parcial:

Bitmap bmp2;

OnLoad:

bmp2 = new Bitmap(Tycoon.Properties.Resources.save2); pictureBox6.SizeMode = PictureBoxSizeMode.StretchImage; pictureBox6.Image = bmp2;

Botón o OnClick

private void pictureBox6_Click(object sender, EventArgs e) { if (bmp2 != null) { bmp2.RotateFlip(RotateFlipType.Rotate90FlipNone); pictureBox6.Image = bmp2; } }


La imagen giratoria es una cosa, los límites adecuados de la imagen en otra. Aquí hay un código que puede ayudar a cualquiera. Creé esto basado en algunas búsquedas en Internet hace mucho tiempo.

/// <summary> /// Rotates image in radian angle /// </summary> /// <param name="bmpSrc"></param> /// <param name="theta">in radian</param> /// <param name="extendedBitmapBackground">Because of rotation returned bitmap can have different boundaries from original bitmap. This color is used for filling extra space in bitmap</param> /// <returns></returns> public static Bitmap RotateImage(Bitmap bmpSrc, double theta, Color? extendedBitmapBackground = null) { theta = Convert.ToSingle(theta * 180 / Math.PI); Matrix mRotate = new Matrix(); mRotate.Translate(bmpSrc.Width / -2, bmpSrc.Height / -2, MatrixOrder.Append); mRotate.RotateAt((float)theta, new Point(0, 0), MatrixOrder.Append); using (GraphicsPath gp = new GraphicsPath()) { // transform image points by rotation matrix gp.AddPolygon(new Point[] { new Point(0, 0), new Point(bmpSrc.Width, 0), new Point(0, bmpSrc.Height) }); gp.Transform(mRotate); PointF[] pts = gp.PathPoints; // create destination bitmap sized to contain rotated source image Rectangle bbox = BoundingBox(bmpSrc, mRotate); Bitmap bmpDest = new Bitmap(bbox.Width, bbox.Height); using (Graphics gDest = Graphics.FromImage(bmpDest)) { if (extendedBitmapBackground != null) { gDest.Clear(extendedBitmapBackground.Value); } // draw source into dest Matrix mDest = new Matrix(); mDest.Translate(bmpDest.Width / 2, bmpDest.Height / 2, MatrixOrder.Append); gDest.Transform = mDest; gDest.DrawImage(bmpSrc, pts); return bmpDest; } } } private static Rectangle BoundingBox(Image img, Matrix matrix) { GraphicsUnit gu = new GraphicsUnit(); Rectangle rImg = Rectangle.Round(img.GetBounds(ref gu)); // Transform the four points of the image, to get the resized bounding box. Point topLeft = new Point(rImg.Left, rImg.Top); Point topRight = new Point(rImg.Right, rImg.Top); Point bottomRight = new Point(rImg.Right, rImg.Bottom); Point bottomLeft = new Point(rImg.Left, rImg.Bottom); Point[] points = new Point[] { topLeft, topRight, bottomRight, bottomLeft }; GraphicsPath gp = new GraphicsPath(points, new byte[] { (byte)PathPointType.Start, (byte)PathPointType.Line, (byte)PathPointType.Line, (byte)PathPointType.Line }); gp.Transform(matrix); return Rectangle.Round(gp.GetBounds()); }


Método simple:

public Image RotateImage(Image img) { var bmp = new Bitmap(img); using (Graphics gfx = Graphics.FromImage(bmp)) { gfx.Clear(Color.White); gfx.DrawImage(img, 0, 0, img.Width, img.Height); } bmp.RotateFlip(RotateFlipType.Rotate270FlipNone); return bmp; }


Puedes hacerlo fácilmente llamando a este método:

public static Bitmap RotateImage(Image image, float angle) { if (image == null) throw new ArgumentNullException("image"); PointF offset = new PointF((float)image.Width / 2, (float)image.Height / 2); //create a new empty bitmap to hold rotated image Bitmap rotatedBmp = new Bitmap(image.Width, image.Height); rotatedBmp.SetResolution(image.HorizontalResolution, image.VerticalResolution); //make a graphics object from the empty bitmap Graphics g = Graphics.FromImage(rotatedBmp); //Put the rotation point in the center of the image g.TranslateTransform(offset.X, offset.Y); //rotate the image g.RotateTransform(angle); //move the image back g.TranslateTransform(-offset.X, -offset.Y); //draw passed in image onto graphics object g.DrawImage(image, new PointF(0, 0)); return rotatedBmp; }

no olvides agregar una referencia a System.Drawing.dll en tu proyecto

Ejemplo de esta llamada a método:

Image image = new Bitmap("waves.png"); Image newImage = RotateImage(image, 360); newImage.Save("newWaves.png");


Richard Cox tiene una buena solución para este https://.com/a/5200280/1171321 que he usado en el pasado. También vale la pena señalar que el DPI debe ser 96 para que esto funcione correctamente. Varias de las soluciones en esta página no funcionan en absoluto.


Una vieja pregunta, pero tuve que abordar el comentario de MrFox en la respuesta aceptada. Al girar una imagen cuando el tamaño cambia, se cortan los bordes de la imagen. Una solución es volver a dibujar el original en una imagen más grande, centrada, donde las dimensiones de la imagen más grande compensan la necesidad de no cortar los bordes. Por ejemplo, quería poder diseñar las fichas de un juego en un ángulo normal, pero volver a dibujarlas en un ángulo de 45 grados para una vista isométrica.

Aquí hay imágenes de ejemplo (los bordes amarillos son para que sea más fácil ver aquí).

La imagen original:

El mosaico centrado en una imagen más grande:

La imagen girada (donde gira la imagen más grande, no la original):

El código (basado en parte en esta respuesta en otra pregunta ):

private Bitmap RotateImage(Bitmap rotateMe, float angle) { //First, re-center the image in a larger image that has a margin/frame //to compensate for the rotated image''s increased size var bmp = new Bitmap(rotateMe.Width + (rotateMe.Width / 2), rotateMe.Height + (rotateMe.Height / 2)); using (Graphics g = Graphics.FromImage(bmp)) g.DrawImageUnscaled(rotateMe, (rotateMe.Width / 4), (rotateMe.Height / 4), bmp.Width, bmp.Height); bmp.Save("moved.png"); rotateMe = bmp; //Now, actually rotate the image Bitmap rotatedImage = new Bitmap(rotateMe.Width, rotateMe.Height); using (Graphics g = Graphics.FromImage(rotatedImage)) { g.TranslateTransform(rotateMe.Width / 2, rotateMe.Height / 2); //set the rotation point as the center into the matrix g.RotateTransform(angle); //rotate g.TranslateTransform(-rotateMe.Width / 2, -rotateMe.Height / 2); //restore rotation point into the matrix g.DrawImage(rotateMe, new Point(0, 0)); //draw the image on the new bitmap } rotatedImage.Save("rotated.png"); return rotatedImage; }