Как перевернуть UIImage по горизонтали с помощью Swift?

Решение для переключения UIImage с помощью кода Objective-C:

[UIImage imageWithCGImage:img.CGImage scale:1.0 orientation: UIImageOrientationDownMirrored]

Однако imageWithCGImage недоступно в Swift! Есть ли решение для переворачивания изображения по горизонтали с помощью Swift? Спасибо!

9 ответов

Решение

Большинство фабричных методов преобразуются в инициализаторы в swift. Всякий раз, когда доступно, даже если метод класса все еще доступен, они предпочтительнее. Ты можешь использовать:

    init(CGImage cgImage: CGImage!, scale: CGFloat, orientation: UIImageOrientation)

Использование будет выглядеть так:

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

Для меня самым простым способом было использовать .withHorizontallyFlippedOrientation() метод экземпляра UIImage следующее:

let flippedImage = straightImage.withHorizontallyFlippedOrientation()

Простые однострочники всегда радуют меня:)

В Свифте.... (6.3.1)

YourUIImage.transform = CGAffineTransformMakeScale(-1, 1)

Это также работает с UIView

Изменение параметра ориентации изображения на самом деле не переворачивает изображение во всех случаях. Изображение должно быть каким-то образом перерисовано... Например, вот так:

Свифт 3

func flipImageLeftRight(_ image: UIImage) -> UIImage? {

    UIGraphicsBeginImageContextWithOptions(image.size, false, image.scale)
    let context = UIGraphicsGetCurrentContext()!
    context.translateBy(x: image.size.width, y: image.size.height)
    context.scaleBy(x: -image.scale, y: -image.scale)

    context.draw(image.cgImage!, in: CGRect(origin:CGPoint.zero, size: image.size))

    let newImage = UIGraphicsGetImageFromCurrentImageContext()

    UIGraphicsEndImageContext()

    return newImage
}

Решение Swift 5

Вот простейшее решение для фактического переворота изображения

extension UIImage {
    func flipHorizontally() -> UIImage? {
        UIGraphicsBeginImageContextWithOptions(self.size, true, self.scale)
        let context = UIGraphicsGetCurrentContext()!
        
        context.translateBy(x: self.size.width/2, y: self.size.height/2)
        context.scaleBy(x: -1.0, y: 1.0)
        context.translateBy(x: -self.size.width/2, y: -self.size.height/2)
        
        self.draw(in: CGRect(x: 0, y: 0, width: self.size.width, height: self.size.height))
        
        let newImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        
        return newImage
    }
}

и чтобы использовать это решение, вы можете сделать следующее

let image = UIImage(named: "image.png")!
let newImage = image.flipHorizontally()

Swift 4

YOURIMAGEVIEW.transform = CGAffineTransform(scaleX: -1, y: 1)

Чтобы быстро перевернуть изображение 4

class ViewController: UIViewController {
var first = 1
var second = 1

@IBOutlet weak var img: UIImageView!
override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.
}

@IBAction func flip1(_ sender: Any) {

    if first == 1 {
        img.transform = CGAffineTransform(scaleX: -1, y: 1)
        first = 2
    }
    else if first == 2
    {
        img.transform = CGAffineTransform(scaleX: +1, y: 1)
        first = 1
    }

}


}

Свифт 5

Если ваш вариант использования требует сохранения UIImageпосле трансформации его нужно будет втянуть в новый CGContext.

      extension UIImage {
  
  enum Axis {
    case horizontal, vertical
  }
  
  func flipped(_ axis: Axis) -> UIImage {
    let renderer = UIGraphicsImageRenderer(size: size)
    
    return renderer.image {
      let context = $0.cgContext
      context.translateBy(x: size.width / 2, y: size.height / 2)
      
      switch axis {
      case .horizontal:
        context.scaleBy(x: -1, y: 1)
      case .vertical:
        context.scaleBy(x: 1, y: -1)
      }
      
      context.translateBy(x: -size.width / 2, y: -size.height / 2)
      
      draw(at: .zero)
    }
  }
}

Есть пара похожих вопросов по SO. И я считаю, что стоит опубликовать решение, используяCoreImage здесь тоже.

Обратите внимание: при получении финала UIImage, необходимо преобразовать в CGImage первым уважать степень CIImage

extension UIImage {
    func imageRotated(by degrees: CGFloat) -> UIImage {

        let orientation = CGImagePropertyOrientation(imageOrientation)
        // Create CIImage respecting image's orientation 
        guard let inputImage = CIImage(image: self)?.oriented(orientation) 
            else { return self }

        // Flip the image itself
        let flip = CGAffineTransform(scaleX: 1, y: -1)
        let outputImage = inputImage.transformed(by: flip)

        // Create CGImage first
        guard let cgImage = CIContext().createCGImage(outputImage, from: outputImage.extent) 
            else { return self }

        // Create output UIImage from CGImage
        return UIImage(cgImage: cgImage)
    }
}
Другие вопросы по тегам