我需要将JPEG图像旋转90度,不幸的是,System.Drawing.Image.RotateFlip产生的文件与我的终端程序不兼容。因此,作为替代方案,我正在尝试使用Graphics.RotateTransform。当前代码似乎应该可以工作,但是图像在旋转时会被剪裁。
This is the image我正在用于测试。
以下是我用来旋转图片的代码:
Public Shared Sub ProcessJpeg()
Dim filePath As String = "C:\test.JPG"
Dim img As Bitmap = Nothing
img = New Bitmap(filePath)
img = RotateImage(img, 90.0F)
img.Save(Replace(filePath, ".JPG", "_new.JPG"))
End Sub
Shared Function RotateImage(b As Bitmap, angle As Single) As Bitmap
'create a new empty bitmap to hold rotated image
Dim returnBitmap As New Bitmap(b.Width, b.Height)
'make a graphics object from the empty bitmap
Dim g As Graphics = Graphics.FromImage(returnBitmap)
'move rotation point to center of image
g.TranslateTransform(CSng(b.Width) / 2, CSng(b.Height) / 2)
'rotate
g.RotateTransform(angle)
'move image back
g.TranslateTransform(-CSng(b.Width) / 2, -CSng(b.Height) / 2)
'draw passed in image onto graphics object
g.DrawImage(b, New Rectangle(New Point(0, 0), New Size(b.Width, b.Height)))
Return returnBitmap
End Function
RotateImage函数来自here。
我认为解决方案是简单地反转b.Width和b.Height在RotateImage函数的第三行到最后一行,但这只会让事情变得更糟。
或者,如果有更好的方法来旋转JPEG(除了System.Drawing.Image.RotateFlip),我很乐意听到它。
答案 0 :(得分:3)
为了不剪切旋转的图像,必须使目标矩形足够大以保持旋转。
以10×5大小的矩形为例。当它旋转时,会有天使渲染大于10x5的图像。如果旋转90度,则只需翻转尺寸。
我以前用过的方法是: 1.创建一个最大尺寸的正方形 (10x5需要大约12x12的正方形。) 2.将图像旋转到正方形的中心。 3.将新方形图像向下剪切到旋转图像的实际大小。
请注意,以下代码适用于任何角度。
此代码将为您提供所需尺寸的正方形。
Public Function SquareRectangle(ByVal Newr As System.Drawing.Rectangle) As System.Drawing.Rectangle
Dim Biggest = Newr.Size.Height
If Newr.Size.Width > Biggest Then
Biggest = Newr.Size.Width
End If
SquareRectangle = New System.Drawing.Rectangle(0, 0, Biggest, Biggest)
End Function
然后 - 此代码将图像放在该正方形的中心。
Public Function CenterBitmap(ByVal OrignalImage As System.Drawing.Bitmap, ByVal SqsR As System.Drawing.Rectangle) As System.Drawing.Bitmap
CenterBitmap = New System.Drawing.Bitmap(SqsR.Size.Width, SqsR.Size.Height)
Dim WPadding = SqsR.Size.Width - OrignalImage.Size.Width
Dim HPadding = SqsR.Size.Height - OrignalImage.Size.Height
Dim Graphics As System.Drawing.Graphics = System.Drawing.Graphics.FromImage(CenterBitmap)
Dim PlaceR As New System.Drawing.Rectangle(CInt(WPadding / 2), CInt(HPadding / 2), OrignalImage.Size.Width, OrignalImage.Size.Height)
Graphics.PageUnit = System.Drawing.GraphicsUnit.Pixel
Graphics.DrawImage(OrignalImage, PlaceR)
End Function
然后 - 旋转正方形后 - 此代码将计算出该正方形内旋转位图的实际大小。
Public Function BoundingBox(ByRef Dimentions As System.Drawing.Size, ByVal Degrees As Single) As System.Drawing.Rectangle
' determine the size needed to hold a rotated rectangle
Dim Rad As Single = CSng((Degrees * Math.PI) / 180)
Dim HalfX As Single = CSng(Dimentions.Width / 2)
Dim HalfY As Single = CSng(Dimentions.Height / 2)
Dim SinRad As Single = CSng(Math.Sin(Rad))
Dim CosRad As Single = CSng(Math.Cos(Rad))
Dim HalfXSinRad As Single = HalfX * SinRad
Dim HalfXCosRad As Single = HalfX * CosRad
Dim HalfYSinRad As Single = HalfY * SinRad
Dim HalfYCosRad As Single = HalfY * CosRad
Dim pXSpYC = HalfXSinRad + HalfYCosRad
Dim pXSnYC = HalfXSinRad + -HalfYCosRad
Dim pXCpYS = HalfXCosRad + HalfYSinRad
Dim pXCnYS = HalfXCosRad + -HalfYSinRad
Dim nXSpYC = -HalfXSinRad + HalfYCosRad
Dim nXSnYC = -HalfXSinRad + -HalfYCosRad
Dim nXCpYS = -HalfXCosRad + HalfYSinRad
Dim nXCnYS = -HalfXCosRad + -HalfYSinRad
Dim x_min = Math.Min(Math.Min(nXCpYS, pXCpYS), Math.Min(pXCnYS, nXCnYS))
Dim x_max = Math.Max(Math.Max(nXCpYS, pXCpYS), Math.Max(pXCnYS, nXCnYS))
Dim y_min = Math.Min(Math.Min(pXSpYC, nXSpYC), Math.Min(nXSnYC, pXSnYC))
Dim y_max = Math.Max(Math.Max(pXSpYC, nXSpYC), Math.Max(nXSnYC, pXSnYC))
BoundingBox = New System.Drawing.Rectangle
BoundingBox.Height = CInt(y_max - y_min)
BoundingBox.Width = CInt(x_max - x_min)
End Function