在Swift中旋转UIImage

我用Swift使用Xcode 6.0.1。 我有一个UIImage,我想使用旧的图像作为源,新的图像旋转以某种方式另一个图像…说垂直翻转。

这个问题已经在几个月前解决了 。 但是,即使情况相同,该解决scheme也不适用于我。

当我有

var image = UIImage(CGImage: otherImage.CGImage, scale: 1.0, orientation: .DownMirrored) 

Xcode抱怨说在调用中有一个“额外的参数”尺度。 在检查Apple文档之后,这是没有意义的,因为该版本的初始化程序确实需要这三个参数。 抛开规模和方向的争论确实解决了这个问题,但阻止了我进行轮换。

我能find的唯一另外一个引用是这个人 ,他有同样的问题。

你怎么看?

我确实需要在这个版本的Xcode上运行,所以如果有一个替代的方法来执行旋转(我还没有find),这将是有用的。

这是对UIImage的简单扩展:

 //ImageRotation.swift import UIKit extension UIImage { public func imageRotatedByDegrees(degrees: CGFloat, flip: Bool) -> UIImage { let radiansToDegrees: (CGFloat) -> CGFloat = { return $0 * (180.0 / CGFloat(M_PI)) } let degreesToRadians: (CGFloat) -> CGFloat = { return $0 / 180.0 * CGFloat(M_PI) } // calculate the size of the rotated view's containing box for our drawing space let rotatedViewBox = UIView(frame: CGRect(origin: CGPointZero, size: size)) let t = CGAffineTransformMakeRotation(degreesToRadians(degrees)); rotatedViewBox.transform = t 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. CGContextTranslateCTM(bitmap, rotatedSize.width / 2.0, rotatedSize.height / 2.0); // // Rotate the image context CGContextRotateCTM(bitmap, degreesToRadians(degrees)); // Now, draw the rotated/scaled image into the context var yFlip: CGFloat if(flip){ yFlip = CGFloat(-1.0) } else { yFlip = CGFloat(1.0) } CGContextScaleCTM(bitmap, yFlip, -1.0) CGContextDrawImage(bitmap, CGRectMake(-size.width / 2, -size.height / 2, size.width, size.height), CGImage) let newImage = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return newImage } } 

( 来源 )

使用它:

 rotatedPhoto = rotatedPhoto?.imageRotatedByDegrees(90, flip: false) 

前者将旋转图像,并翻转如果翻转设置为true。

在Swift 3 for iOS 10中:

 extension UIImage { struct RotationOptions: OptionSet { let rawValue: Int static let flipOnVerticalAxis = RotationOptions(rawValue: 1) static let flipOnHorizontalAxis = RotationOptions(rawValue: 2) } func rotated(by rotationAngle: Measurement<UnitAngle>, options: RotationOptions = []) -> UIImage? { guard let cgImage = self.cgImage else { return nil } let rotationInRadians = CGFloat(rotationAngle.converted(to: .radians).value) let transform = CGAffineTransform(rotationAngle: rotationInRadians) var rect = CGRect(origin: .zero, size: self.size).applying(transform) rect.origin = .zero let renderer = UIGraphicsImageRenderer(size: rect.size) return renderer.image { renderContext in renderContext.cgContext.translateBy(x: rect.midX, y: rect.midY) renderContext.cgContext.rotate(by: rotationInRadians) let x = options.contains(.flipOnVerticalAxis) ? -1.0 : 1.0 let y = options.contains(.flipOnHorizontalAxis) ? 1.0 : -1.0 renderContext.cgContext.scaleBy(x: CGFloat(x), y: CGFloat(y)) let drawRect = CGRect(origin: CGPoint(x: -self.size.width/2, y: -self.size.height/2), size: self.size) renderContext.cgContext.draw(cgImage, in: drawRect) } } } 

你可以像这样使用它:

 let rotatedImage = UIImage(named: "my_amazing_image")?.rotated(by: Measurement(value: 48.0, unit: .degrees)) 

指定翻转标志:

 let flippedImage = UIImage(named: "my_amazing_image")?.rotated(by: Measurement(value: 48.0, unit: .degrees), options: [.flipOnVerticalAxis]) 

当其中一个inputtypes不正确时,通常会发生“额外的参数调用”。

你可以修复你的代码

 var image = UIImage(CGImage: otherImage.CGImage, scale: CGFloat(1.0), orientation: .DownMirrored) 

Swift 3:

向右旋转:

 let image = UIImage(cgImage: otherImage.cgImage!, scale: CGFloat(1.0), orientation: .right) 

testing在游乐场:

 // MyPlayground.playground import UIKit import PlaygroundSupport let view = UIView(frame: CGRect(x: 0, y: 0, width: 500, height: 500)) view.backgroundColor = UIColor.white PlaygroundPage.current.liveView = view let otherImage = UIImage(named: "burger.png", in: Bundle.main, compatibleWith: nil) let imageViewLeft = UIImageView(image: UIImage(cgImage: (otherImage?.cgImage!)!, scale: CGFloat(1.0), orientation: .left)) let imageViewRight = UIImageView(image: UIImage(cgImage: (otherImage?.cgImage!)!, scale: CGFloat(1.0), orientation: .right)) view.addSubview(imageViewLeft) view.addSubview(imageViewRight) view.layoutIfNeeded() 

试试这个代码,它为我工作:

 @IBAction func btnRotateImagePressed(sender: AnyObject) { if let originalImage = self.imageView.image { let rotateSize = CGSize(width: originalImage.size.height, height: originalImage.size.width) UIGraphicsBeginImageContextWithOptions(rotateSize, true, 2.0) if let context = UIGraphicsGetCurrentContext() { CGContextRotateCTM(context, 90.0 * CGFloat(M_PI) / 180.0) CGContextTranslateCTM(context, 0, -originalImage.size.height) originalImage.drawInRect(CGRectMake(0, 0, originalImage.size.width, originalImage.size.height)) self.imageView.image = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() } } } 

@ confile答案更新到Swift 4

 import UIKit extension UIImage { public func imageRotatedByDegrees(degrees: CGFloat, flip: Bool) -> UIImage { let radiansToDegrees: (CGFloat) -> CGFloat = { return $0 * (180.0 / CGFloat.pi) } let degreesToRadians: (CGFloat) -> CGFloat = { return $0 / 180.0 * CGFloat.pi } // calculate the size of the rotated view's containing box for our drawing space let rotatedViewBox = UIView(frame: CGRect(origin: .zero, size: size)) let t = CGAffineTransform(rotationAngle: degreesToRadians(degrees)); rotatedViewBox.transform = t 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) // // Rotate the image context bitmap?.rotate(by: degreesToRadians(degrees)) // 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) let rect = CGRect(x: -size.width / 2, y: -size.height / 2, width: size.width, height: size.height) bitmap?.draw(cgImage!, in: rect) let newImage = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return newImage! } } 

Swift 4解决scheme

这是最简单的解决scheme

 extension UIImage { func rotate(radians: Float) -> UIImage? { var newSize = CGRect(origin: CGPoint.zero, size: self.size).applying(CGAffineTransform(rotationAngle: CGFloat(radians))).size //Trim off the extremely small float value to prevent core graphics from rounding it up newSize.width = floor(newSize.width) newSize.height = floor(newSize.height) UIGraphicsBeginImageContext(newSize); let context = UIGraphicsGetCurrentContext()! //Move origin to middle context.translateBy(x: newSize.width/2, y: newSize.height/2) //Rotate around middle context.rotate(by: CGFloat(radians)) self.draw(in: CGRect(x: -self.size.width/2, y: -self.size.height/2, width: self.size.width, height: self.size.height)) let newImage = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return newImage } }