问题描述
我一直在尝试旋转图像,但遇到了一些问题.第一个代码块正在工作,但它导致了一个不受欢迎的副作用:旋转后,图像被缩小,以便 x
维度将匹配预先存在的 y
维度.
所以我旋转了图像,但它只占据了画布的一部分.
I have been attempting to rotate an Image and I have had some trouble with it. The first block of code was working, but it was causing an undesirable side effect: after the rotation, the Image was scaled down so that the x
dimension would match the preexisting y
dimension.
So I had the Image rotated, but it was only taking up part of the canvas.
为了解决这个问题,我想我应该创建一个更大的位图作为中间步骤,这样当它旋转时,图像就不需要为了适应而缩小.
In order to solve that, I figured I should just create a larger bitmap as an intermediate step, so that when it was rotated, the Image would not need to be shrunk in order to fit.
该代码位于第二个块中.不幸的是,当我运行它时,我收到了一个通用的 GDI 错误.
有谁知道我做错了什么?
That code is in the second block. Unfortunately when I run it, I get a generic GDI error.
Anyone know what I've done wrong?
作品:
Imports System.Drawing
If XSize < YSize Then 'Needs to be rotated
Dim img As Image = Image.FromFile(strFilename)
Dim b = New Bitmap(img.Height, img.Width)
Dim gr As Graphics = Graphics.FromImage(b)
img.RotateFlip(RotateFlipType.Rotate90FlipNone)
gr.DrawImage(img, New Point(0, 0))
img = Nothing
b.Save(strFilename)
End If
这段代码不起作用:
'Needs to be rotated
If XSize < YSize Then
Dim img As Image = Image.FromFile(strFilename)
Dim bmpTemp As Image
If img.Height > img.Width Then
bmpTemp = New Bitmap(img.Height, img.Height)
Else
bmpTemp = New Bitmap(img.Width, img.Width)
End If
Dim gr2 As Graphics = Graphics.FromImage(bmpTemp)
gr2.DrawImage(img, New Point(0, 0))
Dim b = New Bitmap(img.Height, img.Width)
Dim gr As Graphics = Graphics.FromImage(b)
bmpTemp.RotateFlip(RotateFlipType.Rotate90FlipNone)
gr.DrawImage(bmpTemp, New Point(0, 0))
img = Nothing
b.Save(strFilename)
End If
推荐答案
我不太清楚您希望如何旋转图像.问题是旋转轴,旋转图像的新尺寸,还是其他什么?
Not quite clear to me how would you like to rotate the image. Is the problem the rotation axis, the new size of the rotated image, or something else?
无论如何,就我的猜测而言,以下代码片段会围绕画布边缘或围绕其中心点旋转图像.
Anyways, to the best of my guessing, the following code snippet rotates the image either around the edges of the canvas or around it's center point.
Private Function RotateImage(ByVal src As Bitmap,
ByVal width As Integer,
ByVal height As Integer,
ByVal angle As Single,
Optional ByVal CenterRotation As Boolean = False) As Bitmap
Dim cornors As Point() = {New Point(0, 0),
New Point(width, 0),
New Point(width, height),
New Point(0, height)}
Using m As New Matrix
If Not CenterRotation Then
m.RotateAt(angle, New PointF(width / 2, height / 2))
m.TransformPoints(cornors)
End If
Dim left = Integer.MaxValue
Dim right = Integer.MinValue
Dim top = Integer.MaxValue
Dim bottom = Integer.MinValue
For i = 0 To UBound(cornors)
If cornors(i).X < left Then left = cornors(i).X
If cornors(i).X > right Then right = cornors(i).X
If cornors(i).Y < top Then top = cornors(i).Y
If cornors(i).Y > bottom Then bottom = cornors(i).Y
Next
Dim b As New Bitmap(right - left, bottom - top)
Dim x = (b.Width - width) / 2
Dim y = (b.Height - height) / 2
Using g As Graphics = Graphics.FromImage(b)
m.Reset()
m.RotateAt(angle, New PointF(b.Width / 2, b.Height / 2))
g.Transform = m
g.InterpolationMode = InterpolationMode.HighQualityBicubic
g.SmoothingMode = SmoothingMode.HighQuality
g.CompositingQuality = CompositingQuality.HighQuality
g.Clear(Color.Transparent)
g.DrawImage(src, New Rectangle(x, y, width, height))
End Using
Return b
End Using
End Function
如果您还需要调整旋转图像的大小以适合画布,那么在第一个之后您还需要以下代码:
If you also need to resize the rotated image to fit into the canvas, then you also need the following code AFTER THE FIRST ONE:
Private Function CreateThumbnail(ByVal bmp As Bitmap,
ByVal canvasWidth As Integer,
ByVal canvasHeight As Integer,
Optional Stretch As Boolean = False) As Bitmap
Dim bmpOut As Bitmap = Nothing
If Stretch Then
bmpOut = bmp.GetThumbnailImage(canvasWidth, canvasHeight, Nothing, IntPtr.Zero)
Else
Dim newWidth As Integer = 0
Dim newHeight As Integer = 0
bmpOut = New Bitmap(canvasWidth, canvasHeight)
Dim ratioX As Double = CDbl(canvasWidth) / CDbl(bmp.Width)
Dim ratioY As Double = CDbl(canvasHeight) / CDbl(bmp.Height)
Dim ratio = If(ratioX < ratioY, ratioX, ratioY)
newWidth = Convert.ToInt32(bmp.Width * ratio)
newHeight = Convert.ToInt32(bmp.Height * ratio)
If newWidth > bmp.Width Then
newWidth = bmp.Width
End If
If newHeight > bmp.Height Then
newHeight = bmp.Height
End If
Dim posX = Convert.ToInt32((canvasWidth - newWidth) / 2)
Dim posY = Convert.ToInt32((canvasHeight - newHeight) / 2)
Using g As Graphics = Graphics.FromImage(bmpOut)
g.InterpolationMode = InterpolationMode.HighQualityBicubic
g.SmoothingMode = SmoothingMode.HighQuality
g.CompositingQuality = CompositingQuality.HighQuality
g.Clear(Color.Transparent)
g.DrawImage(bmp, posX, posY, newWidth, newHeight)
End Using
End If
Return bmpOut
End Function
这是一个快速演示:
祝你好运.
这篇关于如何旋转图像保留其原始大小?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!