旋转图像而不用GDI +剪切边缘的最快方法是什么?

这样做有一些looooong和饥饿的算法,但到目前为止我还没有提出或发现任何特别快的事情。

最快的方法是使用不安全的调用直接使用LockBits操作图像内存。 这听起来很可怕,但它非常直接。 如果你搜索LockBits,你会发现很多例子,比如这里 。

有趣的是:

 BitmapData originalData = originalBitmap.LockBits( new Rectangle(0, 0, originalWidth, originalHeight), ImageLockMode.ReadOnly, PixelFormat.Format32bppRgb); 

获得BitmapData后,您可以传递像素并将它们映射到新图像(再次使用LockBits)。 这比使用Graphics API快得多。

这是我最终做的事情(经过大量的持续研究,以及TheCodeKing提供的有用链接):

 public Image RotateImage(Image img, float rotationAngle) { // When drawing the returned image to a form, modify your points by // (-(img.Width / 2) - 1, -(img.Height / 2) - 1) to draw for actual co-ordinates. //create an empty Bitmap image Bitmap bmp = new Bitmap((img.Width * 2), (img.Height *2)); //turn the Bitmap into a Graphics object Graphics gfx = Graphics.FromImage(bmp); //set the point system origin to the center of our image gfx.TranslateTransform((float)bmp.Width / 2, (float)bmp.Height / 2); //now rotate the image gfx.RotateTransform(rotationAngle); //move the point system origin back to 0,0 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; //draw our new image onto the graphics object with its center on the center of rotation gfx.DrawImage(img, new PointF((img.Width / 2), (img.Height / 2))); //dispose of our Graphics object gfx.Dispose(); //return the image return bmp; } 

干杯!

 void Graphics.RotateTransform(float angle); 

这应该在C#中旋转图像。 它做了什么呢?

我没有用GDI +进行太多实验。 记住在绘制图像后反转旋转。

这个答案既返回它应该绘制的偏移量和已经旋转的图像。它通过将新图像重建为应该没有剪切角度的大小来工作。 最初由Hisenburg从#C#IRC聊天室和Bloodyaugust撰写。

  public static double NormalizeAngle(double angle) { double division = angle / (Math.PI / 2); double fraction = Math.Ceiling(division) - division; return (fraction * Math.PI / 2); } public static Tuple RotateImage(Image img, double rotationAngle) { double normalizedRotationAngle = NormalizeAngle(rotationAngle); double widthD = img.Width, heightD = img.Height; double newWidthD, newHeightD; newWidthD = Math.Cos(normalizedRotationAngle) * widthD + Math.Sin(normalizedRotationAngle) * heightD; newHeightD = Math.Cos(normalizedRotationAngle) * heightD + Math.Sin(normalizedRotationAngle) * widthD; int newWidth, newHeight; newWidth = (int)Math.Ceiling(newWidthD); newHeight = (int)Math.Ceiling(newHeightD); Size offset = new Size((newWidth - img.Width) / 2,(newHeight - img.Height) / 2); Bitmap bmp = new Bitmap(newWidth, newHeight); Graphics gfx = Graphics.FromImage(bmp); //gfx.Clear(Color.Blue); gfx.TranslateTransform((float)bmp.Width / 2, (float)bmp.Height / 2); gfx.RotateTransform((float)(rotationAngle / Math.PI * 180)); gfx.TranslateTransform(-(float)bmp.Width / 2, -(float)bmp.Height / 2); gfx.InterpolationMode = InterpolationMode.HighQualityBicubic; gfx.DrawImage(img, new PointF((bmp.Width / 2 - img.Width / 2), (bmp.Height / 2 - img.Height / 2))); gfx.Dispose(); return new Tuple(bmp,offset); } 
 System.Drawing.Image imageToRotate = System.Drawing.Image.FromFile(imagePath); switch (rotationAngle.Value) { case "90": imageToRotate.RotateFlip(RotateFlipType.Rotate90FlipNone); break; case "180": imageToRotate.RotateFlip(RotateFlipType.Rotate180FlipNone); break; case "270": imageToRotate.RotateFlip(RotateFlipType.Rotate270FlipNone); break; default: throw new Exception("Rotation angle not supported."); } imageToRotate.Save(imagePath, ImageFormat.Jpeg);