Swift中旋转UIImage

67

我正在使用带有Swift的Xcode 6.0.1。我有一个UIImage,并且我想使用旧图像作为源来制作另一张图像,新图像在某种方式下被旋转...例如垂直翻转。

这个问题已经在几个月前得到了回答(链接)。但是,那个解决方案对我不起作用,即使情况完全相同。

当我有

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

Xcode 抱怨"调用中存在额外的参数 'scale'"。在查阅了苹果文档后,这毫无意义,因为该初始化程序版本确实使用了这三个参数。虽然省略比例和方向参数可以解决问题,但会阻止我进行旋转。

我能找到的唯一其他参考资料是这位遇到了相同的问题。

你觉得呢?

我需要在这个Xcode版本上运行它,所以如果有其他方式来执行旋转(我还没有找到),那将会很有用。


2
Xcode 6.0.1已经过时(不确定是否是问题所在)。您的代码在我的Xcode 6.1中编译没有错误或警告。只有当您省略.CGImage(如参考的github页面)时,才会出现编译器错误。 - Martin R
如果您愿意,在这个Q/A中,您可以轻松地旋转图像视图并绘制图像。https://dev59.com/XVgR5IYBdhLWcg3ww_ze - Khaled Annajar
13个回答

2

针对 Swift 4.2

extension UIImage {


func rotate(_ radians: CGFloat) -> UIImage {
    let cgImage = self.cgImage!
    let LARGEST_SIZE = CGFloat(max(self.size.width, self.size.height))
    let context = CGContext.init(data: nil, width:Int(LARGEST_SIZE), height:Int(LARGEST_SIZE), bitsPerComponent: cgImage.bitsPerComponent, bytesPerRow: 0, space: cgImage.colorSpace!, bitmapInfo: cgImage.bitmapInfo.rawValue)!

    var drawRect = CGRect.zero
    drawRect.size = self.size
    let drawOrigin = CGPoint(x: (LARGEST_SIZE - self.size.width) * 0.5,y: (LARGEST_SIZE - self.size.height) * 0.5)
    drawRect.origin = drawOrigin
    var tf = CGAffineTransform.identity
    tf = tf.translatedBy(x: LARGEST_SIZE * 0.5, y: LARGEST_SIZE * 0.5)
    tf = tf.rotated(by: CGFloat(radians))
    tf = tf.translatedBy(x: LARGEST_SIZE * -0.5, y: LARGEST_SIZE * -0.5)
    context.concatenate(tf)
    context.draw(cgImage, in: drawRect)
    var rotatedImage = context.makeImage()!

    drawRect = drawRect.applying(tf)

    rotatedImage = rotatedImage.cropping(to: drawRect)!
    let resultImage = UIImage(cgImage: rotatedImage)
    return resultImage
}
}

1
这适用于iOS 8及以上版本,并保持图像质量。这是UIImage的两个扩展程序。
  extension UIImage {
    func withSize(_ width: CGFloat, _ height: CGFloat) -> UIImage {

      let target = CGSize(width, height)

      var scaledImageRect = CGRect.zero

      let aspectWidth:CGFloat = target.width / self.size.width
      let aspectHeight:CGFloat = target.height / self.size.height
      let aspectRatio:CGFloat = min(aspectWidth, aspectHeight)

      scaledImageRect.size.width = self.size.width * aspectRatio
      scaledImageRect.size.height = self.size.height * aspectRatio
      scaledImageRect.origin.x = (target.width - scaledImageRect.size.width) / 2.0
      scaledImageRect.origin.y = (target.height - scaledImageRect.size.height) / 2.0

      UIGraphicsBeginImageContextWithOptions(target, false, 0)

      self.draw(in: scaledImageRect)

      let scaledImage = UIGraphicsGetImageFromCurrentImageContext()
      UIGraphicsEndImageContext()

      return scaledImage!
    }

    func rotated(degrees: Double) -> UIImage {

      let radians = CGFloat(Double.pi * degrees / 180)

      var rotatedViewBox: UIView? = UIView(frame: CGRect(x: 0, y: 0, width: size.width * scale, height: size.height * scale))
      let t = CGAffineTransform(rotationAngle: radians)
      rotatedViewBox!.transform = t
      let rotatedSize = rotatedViewBox!.frame.size
      rotatedViewBox = nil

      // 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, y: rotatedSize.height/2)

      //   // Rotate the image context
      bitmap.rotate(by: radians)

      // Now, draw the rotated/scaled image into the context
      bitmap.scaleBy(x: 1.0, y: -1.0)
      bitmap.draw(cgImage!, in: CGRect(x:-size.width * scale / 2, y: -size.height * scale / 2, width: size.width * scale, height: size.height * scale))

      let newImage = UIGraphicsGetImageFromCurrentImageContext()!
      UIGraphicsEndImageContext()

      return newImage.withSize(newImage.size.width/scale, newImage.size.height/scale)
    }
  }

0

请检查:

func rotatedImage(with angle: CGFloat) -> UIImage {

    let updatedSize = CGRect(origin: .zero, size: size)
        .applying(CGAffineTransform(rotationAngle: angle))
        .size

    return UIGraphicsImageRenderer(size: updatedSize)
        .image { _ in

            let context = UIGraphicsGetCurrentContext()

            context?.translateBy(x: updatedSize.width / 2.0, y: updatedSize.height / 2.0)
            context?.rotate(by: angle)

            draw(in: CGRect(x: -size.width / 2.0, y: -size.height / 2.0, width: size.width, height: size.height))
        }
        .withRenderingMode(renderingMode)
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接