2017-02-23 33 views
0

我發現了幾種方法可以在Swift中逐級旋轉圖像,但沒有人能夠始終正常工作。我想將圖像左右旋轉90度。我認爲最好的一個是這樣的:Swift - 以度爲單位的圖像旋轉 - 變形結果

class func imageRotated(_ oldImage: UIImage, byDegrees 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.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 
    } 

它的工作原理,並做我想做的,但也有幾次,當它deformes結果,所以它不旋轉,只是圖像大小被改變,或者它是由180度和圖像尺寸旋轉被改變。

循環之前:

Image before rotation

Afteer旋轉(菜單丟失,因爲它會自動隱藏):

Image after rotation

有什麼奇怪的是,這發生在我參加的人像照片。當我在風景中拍攝照片時,旋轉效果很好(即使我嘗試多次旋轉,即使從風景轉換爲縱向,再次轉換爲風景,仍然可以正常工作)。

我看到了有關自動佈局約束問題進行一些討論,但我不知道這是否是我的問題,爲什麼它會爲某些情況下工作,對一些不會。我在收藏單元格中有照片,每個單元格都有第一個UIScrollView,而在UIScrollView中有UIImageView和照片。所有約束都設置爲界限。

如果它有幫助,我只想旋轉90或-90度。這可能會使方法更簡單,修復更容易。

感謝您的任何幫助。

+0

嘗試使用 self.imageview。transform = CGAffineTransformMakeRotation(M_PI_2); – tejas

+0

@tejas問題不在於旋轉'UIImageView',而是'UIImage'本身 – alexburtnik

+0

@Libor請顯示您如何使用此方法並仔細檢查'imageView'的contentMode。它似乎是'ScaleToFill',它假設失真 – alexburtnik

回答

2

其實最簡單,可能是最好的方法是創建一個視圖,把圖像視圖上,旋轉圖像視圖,調整上海華和創建視圖的屏幕截圖。

其實你不添加視圖層次結構這些觀點,你只是用他們輕鬆地生成圖像。

爲什麼這是一個很好的程序是因爲UIView已經全部寫在它完全支持核心顯卡的代碼。所以根本沒有缺點,你可以肯定這些程序已經被Apple拋光了。

那麼試試這個:

func transformImage(image: UIImage?, transform: CGAffineTransform) -> UIImage? { 

     guard let image = image else { 
      return nil 
     } 

     let view = UIView(frame: CGRect.zero) 
     let imageView = UIImageView(image: image) 
     imageView.transform = transform 
     view.addSubview(imageView) 
     imageView.frame.origin = CGPoint.zero 
     view.frame = CGRect(x: 0.0, y: 0.0, width: imageView.frame.size.width, height: imageView.frame.size.height) 


     UIGraphicsBeginImageContext(view.frame.size) 
     view.layer.render(in: UIGraphicsGetCurrentContext()!) 
     let newImage = UIGraphicsGetImageFromCurrentImageContext() 
     UIGraphicsEndImageContext() 

     if let cgImage = newImage?.cgImage { 
      return UIImage(cgImage: cgImage) 
     } else { 
      return nil 
     } 

    } 

至於在你的程序中的問題,因爲你放棄從UIImage變換是最有可能的。 CGImage基本上是一個原始圖像表示,它不知道旋轉。 UIImage確實有imageOrientation。所以你需要做的是解決這個問題,你需要從圖像方向生成轉換矩陣並使用它。

因此,當你拍攝圖像使用您的設備CGImage將始終具有相同的方向(左或右橫向)。但UIImage將改變圖像的方向,然後用於表示。

+0

看起來你的解決方案很好。謝謝 –

+0

@LiborZapletal我希望你明白你的問題在哪裏。嘗試以肖像拍照並檢查UIImage的大小和CGImage的大小。它們將不會與CGImage仍然處於風景中相同,而UIImage包含它需要旋轉的信息併爲您提供縱向尺寸。 –

+0

是的,它也可以幫助我。我在想這可能是這樣的問題。但我不確定問題出在哪裏,我該如何解決。使用您的解決方案更容易,看起來沒有性能下降。 –