UIImage turn in fast

I want to rotate UIImage clockwise. But my current code does not fulfill a function, more precisely, for a while, when it rotates, and for a while its slippage. I want my UIImage to constantly rotate clockwise on my action button. Here is my current code:

imageView.image = imageView.image!.imageRotatedByDegrees(angle, flip: false) angle = angle + 90 if angle > 360{ angle = 0 } 
+12
source share
6 answers

This works for me:

works great:)

 func imageRotatedByDegrees(oldImage: UIImage, deg degrees: CGFloat) -> UIImage { //Calculate the size of the rotated view containing box for our drawing space let rotatedViewBox: UIView = UIView(frame: CGRectMake(0, 0, oldImage.size.width, oldImage.size.height)) let t: CGAffineTransform = CGAffineTransformMakeRotation(degrees * CGFloat(M_PI / 180)) rotatedViewBox.transform = t let rotatedSize: CGSize = rotatedViewBox.frame.size //Create the bitmap context UIGraphicsBeginImageContext(rotatedSize) let bitmap: CGContextRef = UIGraphicsGetCurrentContext()! //Move the origin to the middle of the image so we will rotate and scale around the center. CGContextTranslateCTM(bitmap, rotatedSize.width / 2, rotatedSize.height / 2) //Rotate the image context CGContextRotateCTM(bitmap, (degrees * CGFloat(M_PI / 180))) //Now, draw the rotated/scaled image into the context CGContextScaleCTM(bitmap, 1.0, -1.0) CGContextDrawImage(bitmap, CGRectMake(-oldImage.size.width / 2, -oldImage.size.height / 2, oldImage.size.width, oldImage.size.height), oldImage.CGImage) let newImage: UIImage = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return newImage } 

Swift 3:

 func imageRotatedByDegrees(oldImage: UIImage, deg degrees: CGFloat) -> UIImage { //Calculate the size of the rotated view 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.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.pi / 180)) //Now, draw the rotated/scaled image into the context bitmap.scaleBy(x: 1.0, y: -1.0) bitmap.draw(oldImage.cgImage!, in: CGRect(x: -oldImage.size.width / 2, y: -oldImage.size.height / 2, width: oldImage.size.width, height: oldImage.size.height)) let newImage: UIImage = UIGraphicsGetImageFromCurrentImageContext()! UIGraphicsEndImageContext() return newImage } 
+21
source
 extension UIImage { public func imageRotatedByDegrees(degrees: CGFloat) -> UIImage { //Calculate the size of the rotated view containing box for our drawing space let rotatedViewBox: UIView = UIView(frame: CGRect(x: 0, y: 0, width: self.size.width, height: self.size.height)) let t: CGAffineTransform = CGAffineTransform(rotationAngle: degrees * CGFloat.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.pi / 180)) //Now, draw the rotated/scaled image into the context bitmap.scaleBy(x: 1.0, y: -1.0) bitmap.draw(self.cgImage!, in: CGRect(x: -self.size.width / 2, y: -self.size.height / 2, width: self.size.width, height: self.size.height)) let newImage: UIImage = UIGraphicsGetImageFromCurrentImageContext()! UIGraphicsEndImageContext() return newImage } public func fixedOrientation() -> UIImage { if imageOrientation == UIImageOrientation.up { return self } var transform: CGAffineTransform = CGAffineTransform.identity switch imageOrientation { case UIImageOrientation.down, UIImageOrientation.downMirrored: transform = transform.translatedBy(x: size.width, y: size.height) transform = transform.rotated(by: CGFloat.pi) break case UIImageOrientation.left, UIImageOrientation.leftMirrored: transform = transform.translatedBy(x: size.width, y: 0) transform = transform.rotated(by: CGFloat.pi/2) break case UIImageOrientation.right, UIImageOrientation.rightMirrored: transform = transform.translatedBy(x: 0, y: size.height) transform = transform.rotated(by: -CGFloat.pi/2) break case UIImageOrientation.up, UIImageOrientation.upMirrored: break } switch imageOrientation { case UIImageOrientation.upMirrored, UIImageOrientation.downMirrored: transform.translatedBy(x: size.width, y: 0) transform.scaledBy(x: -1, y: 1) break case UIImageOrientation.leftMirrored, UIImageOrientation.rightMirrored: transform.translatedBy(x: size.height, y: 0) transform.scaledBy(x: -1, y: 1) case UIImageOrientation.up, UIImageOrientation.down, UIImageOrientation.left, UIImageOrientation.right: break } let ctx: CGContext = CGContext(data: nil, width: Int(size.width), height: Int(size.height), bitsPerComponent: self.cgImage!.bitsPerComponent, bytesPerRow: 0, space: self.cgImage!.colorSpace!, bitmapInfo: CGImageAlphaInfo.premultipliedLast.rawValue)! ctx.concatenate(transform) switch imageOrientation { case UIImageOrientation.left, UIImageOrientation.leftMirrored, UIImageOrientation.right, UIImageOrientation.rightMirrored: ctx.draw(self.cgImage!, in: CGRect(x: 0, y: 0, width: size.height, height: size.width)) default: ctx.draw(self.cgImage!, in: CGRect(x: 0, y: 0, width: size.width, height: size.height)) break } let cgImage: CGImage = ctx.makeImage()! return UIImage(cgImage: cgImage) } } 

@Jason, you have to fix the image orientation before rotation.

 let image = oldimage.fixedOrientation().imageRotatedByDegrees(90.0) 
+18
source

You can create a function so that the image rotates clockwise forever:

 override func viewDidLoad() { super.viewDidLoad() let kRotationAnimationKey = "com.myapplication.rotationanimationkey" func rotateView(view: UIView, duration: Double = 1) { if view.layer.animationForKey(kRotationAnimationKey) == nil { let rotationAnimation = CABasicAnimation(keyPath: "transform.rotation") rotationAnimation.fromValue = 0.0 rotationAnimation.toValue = Float(M_PI * 2.0) rotationAnimation.duration = duration rotationAnimation.repeatCount = Float.infinity view.layer.addAnimation(rotationAnimation, forKey: kRotationAnimationKey) } } rotateView(self.imageView) } 

Result:

enter image description here

+8
source

@Jason Chitla, I can’t comment yet, so I posted it as a new answer. The above solution from @Albert works, but only for square images. The problem is that

 bitmap.draw(oldImage.cgImage!, in: CGRect(x: -oldImage.size.width / 2, y: -oldImage.size.height / 2, width: oldImage.size.width, height: oldImage.size.height)) 

still uses the original size, so if you rotate it 90 degrees, the aspect is wrong.

What works for me is to use the new rotatedSize, for example:

 func imageRotatedByDegrees(oldImage: UIImage, deg degrees: CGFloat) -> UIImage { //Calculate the size of the rotated view 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(self.cgImage!, in: CGRect(x: -rotatedSize.width / 2, y: -rotatedSize.height / 2, width: rotatedSize.width, height: rotatedSize.height)) let newImage: UIImage = UIGraphicsGetImageFromCurrentImageContext()! UIGraphicsEndImageContext() return newImage } 
+8
source

For those who need code from @Mughees in Swift 3:

 func imageRotatedByDegrees(oldImage: UIImage, deg degrees: CGFloat) -> UIImage { //Calculate the size of the rotated view 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.cgImage!, in: CGRect(x: -oldImage.size.width / 2, y: -oldImage.size.height / 2, width: oldImage.size.width, height: oldImage.size.height)) let newImage: UIImage = UIGraphicsGetImageFromCurrentImageContext()! UIGraphicsEndImageContext() return newImage } 
+3
source

I slightly corrected the first @gleb response function. Size calculation is not needed there. We just have to do it the other way around. Because if you do this with a size of 1149 x 356 with the @gleb function, you get a 357 x 1149 image.

  extension UIImage { public func imageRotatedByDegrees(degrees: CGFloat) -> UIImage { let rotatedSize: CGSize = CGRect(x: 0, y: 0, width: self.size.height, height: self.size.width).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.pi / 180)) //Now, draw the rotated/scaled image into the context bitmap.scaleBy(x: 1.0, y: -1.0) bitmap.draw(self.cgImage!, in: CGRect(x: -self.size.width / 2, y: -self.size.height / 2, width: self.size.width, height: self.size.height)) let newImage: UIImage = UIGraphicsGetImageFromCurrentImageContext()! UIGraphicsEndImageContext() return newImage } } 
0
source

All Articles