我如何旋转任何程度的图像?

我有动画gif和我使用类来解析它的图像(帧)。 这堂课是:

using System; using System.Drawing; using System.Drawing.Imaging; using System.Collections.Generic; using System.IO; public class AnimatedGif { private List mImages = new List(); public AnimatedGif(string path) { Image img = Image.FromFile(path); int frames = img.GetFrameCount(FrameDimension.Time); if (frames = frames) break; img.SelectActiveFrame(FrameDimension.Time, frame); } img.Dispose(); } public List Images { get { return mImages; } } } public class AnimatedGifFrame { private int mDuration; private Image mImage; internal AnimatedGifFrame(Image img, int duration) { mImage = img; mDuration = duration; } public Image Image { get { return mImage; } } public int Duration { get { return mDuration; } } } 

现在在form1中,我在这种情况下循环遍历帧4,我想以任何角度旋转动画。 现在它每转45或90度。 我想为动画添加更多帧(图像),所以如果我将旋转设置为31或10度,那么我将看到动画旋转10度。

这是Form1中的代码,它不能正常工作。 我使用旋转function,我没有测试,如果它的任何工作。

 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; namespace AnimatedGifEditor { public partial class Form1 : Form { Image myImage; AnimatedGif myGif; Bitmap bitmap; public Form1() { InitializeComponent(); myImage = Image.FromFile(@"D:\fananimation.gif"); myGif = new AnimatedGif(@"D:\fananimation.gif"); for (int i = 0; i < myGif.Images.Count; i++) { pictureBox1.Image = myGif.Images[3].Image; bitmap = new Bitmap(pictureBox1.Image); rotateImage(bitmap, 76); pictureBox1.Image = bitmap; } } private void Form1_Load(object sender, EventArgs e) { } private Bitmap RotateImg(Bitmap bmp, float angle, Color bkColor) { int w = bmp.Width; int h = bmp.Height; bmp.PixelFormat pf = default(bmp.PixelFormat); if (bkColor == Color.Transparent) { pf = bmp.Format32bppArgb; } else { pf = bmp.PixelFormat; } Bitmap tempImg = new Bitmap(w, h, pf); Graphics g = Graphics.FromImage(tempImg); g.Clear(bkColor); g.DrawImageUnscaled(bmp, 1, 1); g.Dispose(); GraphicsPath path = new GraphicsPath(); path.AddRectangle(new RectangleF(0f, 0f, w, h)); Matrix mtrx = new Matrix(); //Using System.Drawing.Drawing2D.Matrix class mtrx.Rotate(angle); RectangleF rct = path.GetBounds(mtrx); Bitmap newImg = new Bitmap(Convert.ToInt32(rct.Width), Convert.ToInt32(rct.Height), pf); g = Graphics.FromImage(newImg); g.Clear(bkColor); g.TranslateTransform(-rct.X, -rct.Y); g.RotateTransform(angle); g.InterpolationMode = InterpolationMode.HighQualityBilinear; g.DrawImageUnscaled(tempImg, 0, 0); g.Dispose(); tempImg.Dispose(); return newImg; } } } 

可以在这里找到用于测试的动画gif:

在此处输入图像描述

我不明白你的问题是什么,但我认为你的代码可以改进。 我认为您不需要直接使用Matrix类。 有一些function可以帮助您。 事实上,您唯一需要的是:将旋转点设置为中心,旋转图形并在其上绘制,使用Graphics类的某些function。 因此,要旋转图像,您可以使用以下简单代码:

 private Bitmap RotateImage(Bitmap bmp, float angle) { Bitmap rotatedImage = new Bitmap(bmp.Width, bmp.Height); using (Graphics g = Graphics.FromImage(rotatedImage)) { // Set the rotation point to the center in the matrix g.TranslateTransform(bmp.Width / 2, bmp.Height / 2); // Rotate g.RotateTransform(angle); // Restore rotation point in the matrix g.TranslateTransform(- bmp.Width / 2, - bmp.Height / 2); // Draw the image on the bitmap g.DrawImage(bmp, new Point(0, 0)); } return rotatedImage; } 

你试过RotateFlip吗?

 public partial class Form1 : Form { Image myImage; AnimatedGif myGif; Bitmap bitmap; public Form1() { InitializeComponent(); myImage = Image.FromFile(@"D:\fananimation.gif"); bitmap = new Bitmap(myImage); bitmap.RotateFlip(System.Drawing.RotateFlipType.Rotate90FlipNone); this.pictureBox1.Image = bitmap; } } 

资源

基于之前的答案,我创建了这个不会剪切图像的代码(其他示例对我不起作用)

  private Bitmap RotateImage(Bitmap bmp, float angle) { float height = bmp.Height; float width = bmp.Width; int hypotenuse = System.Convert.ToInt32(System.Math.Floor(Math.Sqrt(height * height + width * width))); Bitmap rotatedImage = new Bitmap(hypotenuse, hypotenuse); using (Graphics g = Graphics.FromImage(rotatedImage)) { g.TranslateTransform((float)rotatedImage.Width / 2, (float)rotatedImage.Height / 2); //set the rotation point as the center into the matrix g.RotateTransform(angle); //rotate g.TranslateTransform(-(float)rotatedImage.Width / 2, -(float)rotatedImage.Height / 2); //restore rotation point into the matrix g.DrawImage(bmp, (hypotenuse - width) / 2, (hypotenuse - height) / 2, width, height); } return rotatedImage; } 

我自己尝试了Omar Mahili的答案,并意识到,原始图像在两侧切割……我已经重写了它,因此它将图像调整为新尺寸:

 private static Bitmap RotateImage(Bitmap bmp, float angle) { float alpha = angle; //edit: negative angle +360 while(alpha <0) alpha +=360; float gamma = 90; float beta = 180 - angle - gamma; float c1 = bmp.Height; float a1 = (float)(c1 * Math.Sin(alpha * Math.PI / 180) / Math.Sin(gamma * Math.PI / 180)); float b1 = (float)(c1 * Math.Sin(beta * Math.PI / 180) / Math.Sin(gamma * Math.PI / 180)); float c2 = bmp.Width; float a2 = (float)(c2 * Math.Sin(alpha * Math.PI / 180) / Math.Sin(gamma * Math.PI / 180)); float b2 = (float)(c2 * Math.Sin(beta * Math.PI / 180) / Math.Sin(gamma * Math.PI / 180)); int width = Convert.ToInt32(b2 + a1); int height = Convert.ToInt32(b1 + a2); Bitmap rotatedImage = new Bitmap(width, height); using (Graphics g = Graphics.FromImage(rotatedImage)) { g.TranslateTransform(rotatedImage.Width / 2, rotatedImage.Height / 2); //set the rotation point as the center into the matrix g.RotateTransform(angle); //rotate g.TranslateTransform(-rotatedImage.Width / 2, -rotatedImage.Height / 2); //restore rotation point into the matrix g.DrawImage(bmp, new Point((width - bmp.Width) / 2, (height - bmp.Height) / 2)); //draw the image on the new bitmap } return rotatedImage; } 

30度半径大小的变化

我在VB中使用这个函数:

  Public Function RotateImage(ByRef image As Image, ByVal angle As Single) As Drawing.Bitmap If image Is Nothing Then Throw New ArgumentNullException("image") End If Dim pi2 As Single = Math.PI / 2.0 Dim oldWidth As Single = image.Width Dim oldHeight As Single = image.Height Dim theta As Single = angle * Math.PI / 180.0 Dim locked_theta As Single = theta If locked_theta < 0.0 Then locked_theta += 2 * Math.PI Dim newWidth, newHeight As Single Dim nWidth, nHeight As Integer Dim adjacentTop, oppositeTop As Single Dim adjacentBottom, oppositeBottom As Single If (locked_theta >= 0.0 And locked_theta < pi2) Or _ (locked_theta >= Math.PI And locked_theta < (Math.PI + pi2)) Then 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 End If newWidth = adjacentTop + oppositeBottom newHeight = adjacentBottom + oppositeTop nWidth = Int(Math.Ceiling(newWidth)) nHeight = Int(Math.Ceiling(newHeight)) Dim rotatedBmp As New Drawing.Bitmap(nWidth, nHeight) Dim g As Graphics = Graphics.FromImage(rotatedBmp) Dim points(2) As Point If (locked_theta >= 0.0 And locked_theta < pi2) Then points(0) = New Point(Int(oppositeBottom), 0) points(1) = New Point(nWidth, Int(oppositeTop)) points(2) = New Point(0, Int(adjacentBottom)) ElseIf locked_theta >= pi2 And locked_theta < Math.PI Then points(0) = New Point(nWidth, Int(oppositeTop)) points(1) = New Point(Int(adjacentTop), nHeight) points(2) = New Point(Int(oppositeBottom), 0) ElseIf locked_theta >= Math.PI And locked_theta < (Math.PI + pi2) Then points(0) = New Point(Int(adjacentTop), nHeight) points(1) = New Point(0, Int(adjacentBottom)) points(2) = New Point(nWidth, Int(oppositeTop)) Else points(0) = New Point(0, Int(adjacentBottom)) points(1) = New Point(Int(oppositeBottom), 0) points(2) = New Point(Int(adjacentTop), nHeight) End If g.DrawImage(image, points) g.Dispose() image.Dispose() Return rotatedBmp End Function