ios 如何在 Swift 中旋转图像?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/40882487/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to rotate image in Swift?
提问by TechChain
I am unable to rotate the image by 90 degrees in swift. I have written below code but there is an error and doesn't compile
我无法快速将图像旋转 90 度。我写了下面的代码但是有一个错误并且不能编译
func imageRotatedByDegrees(oldImage: UIImage, deg degrees: CGFloat) -> UIImage {
//Calculate the size of the rotated view's containing box for our drawing space
let rotatedViewBox: UIView = UIView(frame: CGRect(x: 0, y: 0, width: oldImage.size.width, height: oldImage.size.height))
let t: CGAffineTransform = CGAffineTransform(rotationAngle: degrees * CGFloat(M_PI / 180))
rotatedViewBox.transform = t
let rotatedSize: CGSize = rotatedViewBox.frame.size
//Create the bitmap context
UIGraphicsBeginImageContext(rotatedSize)
let bitmap: CGContext = UIGraphicsGetCurrentContext()!
//Move the origin to the middle of the image so we will rotate and scale around the center.
bitmap.translateBy(x: rotatedSize.width / 2, y: rotatedSize.height / 2)
//Rotate the image context
bitmap.rotate(by: (degrees * CGFloat(M_PI / 180)))
//Now, draw the rotated/scaled image into the context
bitmap.scaleBy(x: 1.0, y: -1.0)
bitmap.draw(oldImage, in: CGRect(origin: (x: -oldImage.size.width / 2, y: -oldImage.size.height / 2, width: oldImage.size.width, height: oldImage.size.height), size: oldImage.cgImage))
let newImage: UIImage = UIGraphicsGetImageFromCurrentImageContext()!
UIGraphicsEndImageContext()
return newImage
}
below is the code i am not sure about
下面是我不确定的代码
bitmap.draw(oldImage, in: CGRect(origin: (x: -oldImage.size.width / 2, y: -oldImage.size.height / 2, width: oldImage.size.width, height: oldImage.size.height), size: oldImage.cgImage))
采纳答案by CodeBender
This is an extension of UIImage
that targets Swift 4.0and can rotate just the image without the need for a UIImageView
. Tested successfully that the image was rotated, and not just had its exif data changed.
这是UIImage
针对Swift 4.0的扩展,可以仅旋转图像而无需UIImageView
. 成功测试图像已旋转,而不仅仅是更改了 exif 数据。
import UIKit
extension UIImage {
func rotate(radians: CGFloat) -> UIImage {
let rotatedSize = CGRect(origin: .zero, size: size)
.applying(CGAffineTransform(rotationAngle: CGFloat(radians)))
.integral.size
UIGraphicsBeginImageContext(rotatedSize)
if let context = UIGraphicsGetCurrentContext() {
let origin = CGPoint(x: rotatedSize.width / 2.0,
y: rotatedSize.height / 2.0)
context.translateBy(x: origin.x, y: origin.y)
context.rotate(by: radians)
draw(in: CGRect(x: -origin.y, y: -origin.x,
width: size.width, height: size.height))
let rotatedImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return rotatedImage ?? self
}
return self
}
}
To perform a 180 degree rotation, you can call it like this:
要执行 180 度旋转,您可以这样调用:
let rotatedImage = image.rotate(radians: .pi)
If for whatever reason it fails to rotate, the original image will then be returned.
如果由于某种原因无法旋转,则将返回原始图像。
回答by Jayesh Miruliya
set ImageView image
设置 ImageView 图像
ImageView.transform = ImageView.transform.rotated(by: CGFloat(M_PI_2))
Swift 5
斯威夫特 5
ImageView.transform = ImageView.transform.rotated(by: .pi) // 180?
ImageView.transform = ImageView.transform.rotated(by: .pi / 2) // 90?
ImageView.transform = ImageView.transform.rotated(by: .pi * 1.5) // 270?
回答by Aaron Halvorsen
In one line:
在一行中:
rotatedViewBox.transform = CGAffineTransform(rotationAngle: CGFloat.pi/2)
回答by Chirag kukreja
let angle = CGFloat(M_PI_2)
let tr = CGAffineTransform.identity.rotated(by: angle)
ImageView.transform = tr
回答by iOS
In Swift 4.2 and Xcode 10.0
在 Swift 4.2 和 Xcode 10.0 中
dropDownImageView.transform = dropDownImageView.transform.rotated(by: CGFloat(Double.pi / 2))
If you want to add animation...
如果要添加动画...
UIView.animate(withDuration: 2.0, animations: {
self.dropDownImageView.transform = self.dropDownImageView.transform.rotated(by: CGFloat(Double.pi / 2))
})
回答by Smit Yash
You can use the code below for Swift 3:
您可以将以下代码用于 Swift 3:
extension UIImage {
func fixImageOrientation() -> UIImage? {
var flip:Bool = false //used to see if the image is mirrored
var isRotatedBy90:Bool = false // used to check whether aspect ratio is to be changed or not
var transform = CGAffineTransform.identity
//check current orientation of original image
switch self.imageOrientation {
case .down, .downMirrored:
transform = transform.rotated(by: CGFloat(M_PI));
case .left, .leftMirrored:
transform = transform.rotated(by: CGFloat(M_PI_2));
isRotatedBy90 = true
case .right, .rightMirrored:
transform = transform.rotated(by: CGFloat(-M_PI_2));
isRotatedBy90 = true
case .up, .upMirrored:
break
}
switch self.imageOrientation {
case .upMirrored, .downMirrored:
transform = transform.translatedBy(x: self.size.width, y: 0)
flip = true
case .leftMirrored, .rightMirrored:
transform = transform.translatedBy(x: self.size.height, y: 0)
flip = true
default:
break;
}
// calculate the size of the rotated view's containing box for our drawing space
let rotatedViewBox = UIView(frame: CGRect(origin: CGPoint(x:0, y:0), size: size))
rotatedViewBox.transform = transform
let rotatedSize = rotatedViewBox.frame.size
// Create the bitmap context
UIGraphicsBeginImageContext(rotatedSize)
let bitmap = UIGraphicsGetCurrentContext()
// Move the origin to the middle of the image so we will rotate and scale around the center.
bitmap!.translateBy(x: rotatedSize.width / 2.0, y: rotatedSize.height / 2.0);
// Now, draw the rotated/scaled image into the context
var yFlip: CGFloat
if(flip){
yFlip = CGFloat(-1.0)
} else {
yFlip = CGFloat(1.0)
}
bitmap!.scaleBy(x: yFlip, y: -1.0)
//check if we have to fix the aspect ratio
if isRotatedBy90 {
bitmap?.draw(self.cgImage!, in: CGRect(x: -size.width / 2, y: -size.height / 2, width: size.height,height: size.width))
} else {
bitmap?.draw(self.cgImage!, in: CGRect(x: -size.width / 2, y: -size.height / 2, width: size.width,height: size.height))
}
let fixedImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return fixedImage
}
回答by Sarath Raveendran
Rotate image via UIGraphics Context is comparatively heavy operation. The problems you may seen loosing quality and memory increase.
通过 UIGraphics Context 旋转图像是比较繁重的操作。您可能会遇到质量下降和内存下降的问题。
I suggest you should try to rotate the layer or view itself.
我建议您应该尝试旋转图层或查看本身。
extension UIView {
func rotate(degrees: CGFloat) {
let degreesToRadians: (CGFloat) -> CGFloat = { (degrees: CGFloat) in
return degrees / 180.0 * CGFloat.pi
}
self.transform = CGAffineTransform(rotationAngle: degreesToRadians(degrees))
// If you like to use layer you can uncomment the following line
//layer.transform = CATransform3DMakeRotation(degreesToRadians(degrees), 0.0, 0.0, 1.0)
}
}
How to use
如何使用
yourImageView.rotate(degrees: 40)
回答by par
Your code is not that far off from functional. You can apply the transform as you are doing directly to the bitmap, you don't need an intermediate view:
你的代码离功能不远了。您可以直接对位图应用转换,不需要中间视图:
func imageRotatedByDegrees(oldImage: UIImage, deg degrees: CGFloat) -> UIImage {
let size = oldImage.size
UIGraphicsBeginImageContext(size)
let bitmap: CGContext = UIGraphicsGetCurrentContext()!
//Move the origin to the middle of the image so we will rotate and scale around the center.
bitmap.translateBy(x: size.width / 2, y: size.height / 2)
//Rotate the image context
bitmap.rotate(by: (degrees * CGFloat(M_PI / 180)))
//Now, draw the rotated/scaled image into the context
bitmap.scaleBy(x: 1.0, y: -1.0)
let origin = CGPoint(x: -size.width / 2, y: -size.width / 2)
bitmap.draw(oldImage.cgImage!, in: CGRect(origin: origin, size: size))
let newImage: UIImage = UIGraphicsGetImageFromCurrentImageContext()!
UIGraphicsEndImageContext()
return newImage
}
Also, if you're going to create a function that rotates an image, it is typically good form to include a clockwise: Bool
parameter that will interpret the degrees
argument as rotating clockwise or not. The implementation and appropriate conversion to radians I leave to you.
此外,如果您要创建一个旋转图像的函数,通常最好包含一个clockwise: Bool
参数,该参数会将参数解释degrees
为是否顺时针旋转。弧度的实现和适当的转换我留给你。
Also note that it's a bit hand-wavy on my part to assume that oldImage.size
is non-zero. If it is, force-unwrapping UIGraphicsGetCurrentContext()!
will probably crash. You should validate the oldImage
's size and if it's invalid just return oldImage
.
另请注意,假设它oldImage.size
不为零对我来说有点摇摆不定。如果是,强制展开UIGraphicsGetCurrentContext()!
可能会崩溃。您应该验证oldImage
的大小,如果无效则返回oldImage
。
回答by Okan
You can first set your image in imageView and rotate get your image in imageView
您可以先在 imageView 中设置图像并旋转在 imageView 中获取图像
Here:
这里:
let customImageView = UIImageView()
customImageView.frame = CGRect.init(x: 0, y: 0, w: 250, h: 250)
customImageView.image = UIImage(named: "yourImage")
customImageView .transform = customImageView .transform.rotated(by: CGFloat.init(M_PI_2))
var rotatedImage = UIImage()
rotatedImage = customImageView.image!
回答by user1039695
If you just don't want specific rotation and like to use all orientations one by one.
如果您只是不想要特定的旋转并且喜欢一个一个地使用所有方向。
func rotateImage() -> UIImage {
let newOrientation = Orientation(rawValue: self.imageOrientation.rawValue + 1) ?? UIImage.Orientation(rawValue: 0)
return UIImage(cgImage: self.cgImage!, scale: self.scale, orientation: newOrientation!)
}