如何在c#中旋转图像x度?

我做了一些搜索,我找不到任何function,做我想做的事情。

我有一个带有文本的扫描文档的图像文件,但文档旋转了一些度数,所以我想旋转它,使文本相互串联。

在一个完美的世界,它应该是一个自动执行此function的function,但我无法找到任何东西和我理解的自动工作,它需要对图像进行一些分析,我认为这是一件大事。

但后来我已经做了一个工具来手动旋转网站上的图像,但现在我需要一个function来保存旋转到图像文件。

这似乎是一些不同的方法,但没有人我测试做我想做的。

我发现的function几乎就像我的作品一样:

public static Bitmap RotateImg(Bitmap bmp, float angle, Color bkColor) { int w = bmp.Width; int h = bmp.Height; PixelFormat pf = default(PixelFormat); if (bkColor == Color.Transparent) { pf = PixelFormat.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; } 

但这不会改变图像文件的高度和宽度,因此图像文件的大小相同,但图像“对象”已缩放和旋转。

知道我怎么能做到这一点好吗?

回答我找到了解决方案,该解决方案适用于我的图像,其分辨率为300,在旧的答案中 。

如果我已经正确地理解了你的问题,你基本上想要在旋转后计算出图像的新尺寸,以及如何将旋转后的图像定位在它的新位图中。

在此处输入图像描述

该图有望帮助明确解决方案。 这里有一些伪代码:

 sinVal = abs(sin(angle)) cosVal = abs(cos(angle)) newImgWidth = sinVal * oldImgHeight + cosVal * oldImgWidth newImgHeight = sinVal * oldImgWidth + cosVal * oldImgHeight originX = 0 originY = sinVal * oldImgWidth 

您想要从newImgWidth和newImgHeight创建新图像,然后围绕原点(originX,originY)执行旋转,然后将图像渲染到此点。 如果角度(以度为单位)不在-90度和0度之间(如图所示),则会出现这种情况。 如果它介于0和90度之间,那么您只需更改原点:

 originX = sinVal * oldImgHeight originY = 0 

如果它在90度到270度(-90度)的范围内,则它有点小问题(参见下面的示例代码)。

您的代码重写(简要测试) – 它有点狡猾,但似乎工作:

 public static Bitmap RotateImg(Bitmap bmp, float angle, Color bkColor) { angle = angle % 360; if (angle > 180) angle -= 360; System.Drawing.Imaging.PixelFormat pf = default(System.Drawing.Imaging.PixelFormat); if (bkColor == Color.Transparent) { pf = System.Drawing.Imaging.PixelFormat.Format32bppArgb; } else { pf = bmp.PixelFormat; } float sin = (float)Math.Abs(Math.Sin(angle * Math.PI / 180.0)); // this function takes radians float cos = (float)Math.Abs(Math.Cos(angle * Math.PI / 180.0)); // this one too float newImgWidth = sin * bmp.Height + cos * bmp.Width; float newImgHeight = sin * bmp.Width + cos * bmp.Height; float originX = 0f; float originY = 0f; if (angle > 0) { if (angle <= 90) originX = sin * bmp.Height; else { originX = newImgWidth; originY = newImgHeight - sin * bmp.Width; } } else { if (angle >= -90) originY = sin * bmp.Width; else { originX = newImgWidth - sin * bmp.Height; originY = newImgHeight; } } Bitmap newImg = new Bitmap((int)newImgWidth, (int)newImgHeight, pf); Graphics g = Graphics.FromImage(newImg); g.Clear(bkColor); g.TranslateTransform(originX, originY); // offset the origin to our calculated values g.RotateTransform(angle); // set up rotate g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBilinear; g.DrawImageUnscaled(bmp, 0, 0); // draw the image at 0, 0 g.Dispose(); return newImg; } 

注意trig函数的Degrees to Radians Conversion(180 Degrees == Pi Radians)

编辑:大问题是负的罪恶值,并且在计算原点x / y时我得到宽度/高度混淆 – 这应该现在正常工作(测试)

编辑:修改代码以处理任何角度

这完全是对VisualMelon上面的好答案的评论,但是我不允许添加评论……

代码中有两个小错误

a)模数后的第一次检查应分成两部分,或改为例如

 if (180 

否则-360和-180之间的角度将失败,因为仅处理+180至+360

b)在newImg分配之后,缺少解决方案分配,例如

 newImg.SetResolution(bmp.HorizontalResolution, bmp.VerticalResolution); 

如果省略,如果源不是96 dpi,则将缩放图像。

....和分裂棒,尺寸和偏移的中间计算应该保持两倍,并且只能减少到最后浮动