Many probably often met with a small, but common problem, when the image stored in the graphic file has an orientation which is not convenient for viewing, and opens with viewing programs not from the angle from which the user probably would like to view it. Fortunately, even the most primitive image viewers often give the user the ability to rotate an image, at least at multiple angles of 90 °. Some programs, including even the built-in shells of modern cameras, can even predict by what angle the wrongly oriented image file should be rotated and displayed to the user at the right angle.

What means of C # and the .Net platform can realize the ability to change the file with the image, turning the second at a given angle, and saving this change in the first?

    3 answers 3

    /// <summary> /// поворачивает изображение по часовой стрелке или против часовой стрелки /// </summary> /// <param name="img">изображение</param> /// <param name="rotationAngle">угол (в градусах). /// Положительные числа - по часовой стрелке /// отрицательные - против часовой стрелки /// </param> /// <returns></returns> public static Image RotateImage(Image img, float rotationAngle) { Bitmap bmp = new Bitmap(img.Width, img.Height); Graphics gfx = Graphics.FromImage(bmp); gfx.TranslateTransform((float)bmp.Width / 2, (float)bmp.Height / 2); gfx.RotateTransform(rotationAngle); gfx.TranslateTransform(-(float)bmp.Width / 2, -(float)bmp.Height / 2); gfx.InterpolationMode = InterpolationMode.HighQualityBicubic; gfx.DrawImage(img, new Point(0, 0)); gfx.Dispose(); return bmp; } 
    • one
      question about the file, not the Image object - 4per
    • 2
      look here - Ruslan_K

    To be able to change the image in the file. You need to get the Image object from the file, rotate for this object, write the Image to the file. Using the method given in the answer user3373603 , which allows you to rotate the image at an arbitrary angle:

     Image img = null; using (FileStream stream = new FileStream(filepath, FileMode.Open, FileAccess.Read)) { img = Image.FromStream(stream); } if (img != null) { img = RotateImage(img, angle); //angle - угол в градусах img.Save(filepath); } 

    Or, if there are enough rotations at angles of multiples of 90 ° + bonus in the form of the possibility of reflecting the image:

     /// <summary> /// Повернуть изображение в файле на угол и (или) отразить по оси /// </summary> /// <param name="filepath">путь к файлу</param> /// <param name="rft">Член перечисления System.Drawing.RotateFlipType, указывающий тип /// поворота и зеркального отражения, который нужно применить к изображению</param> public static void RotateImageFile(string filepath, System.Drawing.RotateFlipType rft) { Image img = null; using (FileStream stream = new FileStream(filepath, FileMode.Open, FileAccess.Read)) { img = Image.FromStream(stream); } if (img != null) { img.RotateFlip(rft); img.Save(filepath); } } 
    • one
      The main advantage of this method is that it simply changes the RotateFlip flag in the file, rather than expanding the picture itself. - PashaPash

    Your function will cut the image, because new sizes are not calculated, when turning, the sizes will change and everything that is not included in the previous size will be cut off.

     const double DegToRad = 0.017453292519943295; static float NormalizeAngle(float angle) { angle %= 360; if (angle < 0) angle += 360; return angle; } static System.Drawing.Image RotateImage(string fileName, float angle) { System.Drawing.Image image = null; using (System.IO.FileStream stream = new System.IO.FileStream(fileName, System.IO.FileMode.Open, System.IO.FileAccess.Read)) { image = System.Drawing.Image.FromStream(stream); } angle = NormalizeAngle(angle); if(angle % 90 == 0) switch(angle) { case 0: return image; case 90: image.RotateFlip(System.Drawing.RotateFlipType.Rotate90FlipNone); return image; case 180: image.RotateFlip(System.Drawing.RotateFlipType.Rotate180FlipNone); return image; case 270: image.RotateFlip(System.Drawing.RotateFlipType.Rotate270FlipNone); return image; } float sin = (float)Math.Sin(angle % 90 * DegToRad); float cos = (float)Math.Cos(angle % 90 * DegToRad); float oldWidth = image.Width; float oldHeight = image.Height; float newWidth = 0f; float newHeight = 0f; float originX = 0f; float originY = 0f; if ((angle > 0 && angle < 90) || (angle > 180 && angle < 270)) { newWidth = sin * oldHeight + cos * oldWidth; newHeight = sin * oldWidth + cos * oldHeight; if (angle < 90) { originX = sin * oldHeight; originY = 0f; } else { originX = cos * oldWidth; originY = newHeight; } } else if ((angle > 90 && angle < 180) || (angle > 270 && angle < 360)) { newHeight = sin * oldHeight + cos * oldWidth; newWidth = sin * oldWidth + cos * oldHeight; if (angle < 180) { originX = newWidth; originY = sin * oldHeight; } else { originX = 0f; originY = cos * oldWidth; } } System.Drawing.Bitmap bmp = new System.Drawing.Bitmap((int)newWidth, (int)newHeight); bmp.SetResolution(image.HorizontalResolution, image.VerticalResolution); using (System.Drawing.Graphics gr = System.Drawing.Graphics.FromImage(bmp)) { gr.TranslateTransform(originX, originY); gr.RotateTransform(angle); gr.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic; gr.DrawImage(image, new System.Drawing.Point(0, 0)); } return bmp; } 

    Maybe this code does not look very nice (correct, who knows better, I will be very grateful), but it works correctly and the image that the function returns is not cropped, but written in the new dimensions completely and can already be saved to a file.