2016-11-30 14 views
19

Jestem unbale aby obrócić obraz o 90 stopni w szybkim 3.i napisałem poniżej kod, ale to jest o błąd & nie można skompilowaćJak obrócić obraz w Swift 3?

func imageRotatedByDegrees(oldImage: UIImage, deg 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, in: CGRect(origin: (x: -oldImage.size.width/2, y: -oldImage.size.height/2, width: oldImage.size.width, height: oldImage.size.height), size: oldImage.cgImage)) 



    let newImage: UIImage = UIGraphicsGetImageFromCurrentImageContext()! 
    UIGraphicsEndImageContext() 
    return newImage 
    } 

poniższy kod nie jestem w stanie napisać & nie wiem Na czym polega problem z nim

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

http: // stackoverflow.com/a/33479054/291240 –

+2

Podczas otrzymywania błędów, nigdy nie zapomnij powiedzieć ludziom, które to są! –

+0

Zarządzaj warunkami obrazu po wykonaniu z aparatu. I spróbuj tego linku: http://stackoverflow.com/questions/9324130/iphone-image-captured- from-camera-rotate-90-degree-automatically Pomoże to rozwiązać problem. –

Odpowiedz

8
let angle = CGFloat(M_PI_2) 
    let tr = CGAffineTransform.identity.rotated(by: angle) 
    ImageView.transform = tr 
+5

Chcę obrócić UIImage nie na widok obrazu – Techiee

25

zestaw ImageView obraz

ImageView.transform = ImageView.transform.rotated(by: CGFloat(M_PI_2)) 
+2

Dlaczego M_PI_4? 90 stopni = M_PI_2 – alexburtnik

+1

ok ... dzięki @alexburtnik –

+3

@JayeshMiruliya, również w Swift 3 można użyć stałej 'CGFloat.pi' (podzielonej przez 2 ofc) – user28434

0

Twój kod nie jest aż tak daleki od funkcjonalności. Można zastosować transformatę jak robisz bezpośrednio do bitmapy, nie trzeba pośrednią widok:

func imageRotatedByDegrees(oldImage: UIImage, deg degrees: CGFloat) -> UIImage { 
    let size = oldImage.size 

    UIGraphicsBeginImageContext(size) 

    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: size.width/2, y: size.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) 

    let origin = CGPoint(x: -size.width/2, y: -size.width/2) 

    bitmap.draw(oldImage.cgImage!, in: CGRect(origin: origin, size: size)) 

    let newImage: UIImage = UIGraphicsGetImageFromCurrentImageContext()! 
    UIGraphicsEndImageContext() 
    return newImage 
} 

Ponadto, jeśli masz zamiar utworzyć funkcję, która obraca obraz, to zazwyczaj dobry Formularz zawiera parametr clockwise: Bool, który interpretuje argument degrees jako obrót zgodny z ruchem wskazówek zegara lub nie. Wdrożenie i odpowiednia konwersja do radianów pozostawiam Tobie.

Zauważ, że z mojej strony jest trochę niezręcznie, zakładając, że oldImage.size jest niezerowe. Jeśli tak, prawdopodobnie nastąpi awaria wymuszonego rozpakowania. Powinieneś sprawdzić poprawność rozmiaru oldImage, a jeśli jest on nieprawidłowy, po prostu zwróć oldImage.

+0

Funkcjonalny kod nie obraca obrazu o środku, chyba że w wyjątkowym scenariuszu obraz jest kwadratowy. Użyłem metody pośredniej i wykonałem rotację w punkcie środkowym. –

0

Twój problem polega na tym, że używasz nieistniejącego inicjalizatora dla CGRect. Jeśli chcesz użyć CGRect (origin: size :), następnie utwórz poprawnie pochodzenie, bez parametrów szerokości i wysokości. Lub usuń parametr rozmiaru i użyj CGRect (x: y: width: height :).

Wystarczy zastąpić tę linię

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

z tego:

let rect = CGRect(origin: CGPoint(x: -oldImage.size.width/2, y: -oldImage.size.height/2), size: oldImage.size) 
bitmap.draw(oldImage.cgImage!, in: rect) 
6

Można użyć kodu poniżej Swift 3:

extension UIImage { 

func fixImageOrientation() -> UIImage? { 
    var flip:Bool = false //used to see if the image is mirrored 
    var isRotatedBy90:Bool = false // used to check whether aspect ratio is to be changed or not 

    var transform = CGAffineTransform.identity 

    //check current orientation of original image 
    switch self.imageOrientation { 
    case .down, .downMirrored: 
     transform = transform.rotated(by: CGFloat(M_PI)); 

    case .left, .leftMirrored: 
     transform = transform.rotated(by: CGFloat(M_PI_2)); 
     isRotatedBy90 = true 
    case .right, .rightMirrored: 
     transform = transform.rotated(by: CGFloat(-M_PI_2)); 
     isRotatedBy90 = true 
    case .up, .upMirrored: 
     break 
    } 

    switch self.imageOrientation { 

    case .upMirrored, .downMirrored: 
     transform = transform.translatedBy(x: self.size.width, y: 0) 
     flip = true 

    case .leftMirrored, .rightMirrored: 
     transform = transform.translatedBy(x: self.size.height, y: 0) 
     flip = true 
    default: 
     break; 
    } 

    // calculate the size of the rotated view's containing box for our drawing space 
    let rotatedViewBox = UIView(frame: CGRect(origin: CGPoint(x:0, y:0), size: size)) 
    rotatedViewBox.transform = transform 
    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); 

    // 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) 

    //check if we have to fix the aspect ratio 
    if isRotatedBy90 { 
     bitmap?.draw(self.cgImage!, in: CGRect(x: -size.width/2, y: -size.height/2, width: size.height,height: size.width)) 
    } else { 
     bitmap?.draw(self.cgImage!, in: CGRect(x: -size.width/2, y: -size.height/2, width: size.width,height: size.height)) 
    } 

    let fixedImage = UIGraphicsGetImageFromCurrentImageContext() 
    UIGraphicsEndImageContext() 

    return fixedImage 
} 
+1

idealne, dziękuję –

2

można najpierw ustawić obraz w imageView i obróć, aby uzyskać obraz na zdjęciuView

tutaj:

let customImageView = UIImageView() 
customImageView.frame = CGRect.init(x: 0, y: 0, w: 250, h: 250) 
customImageView.image = UIImage(named: "yourImage") 

customImageView .transform = customImageView .transform.rotated(by: CGFloat.init(M_PI_2)) 
var rotatedImage = UIImage() 
rotatedImage = customImageView.image! 
0

Jest przedłużeniem UIImage że cele Swift 4.0 i może się obracać tylko obraz bez konieczności stosowania UIImageView. Przetestowano pomyślnie, że obraz został obrócony, a nie tylko zmieniono jego dane exif.

import UIKit 

extension UIImage { 
    func rotate(radians: CGFloat) -> UIImage { 
     let rotatedSize = CGRect(origin: .zero, size: size).applying(CGAffineTransform(rotationAngle: CGFloat(radians))).integral.size 
     UIGraphicsBeginImageContext(rotatedSize) 
     if let context = UIGraphicsGetCurrentContext() { 
      let origin = CGPoint(x: rotatedSize.width/2.0, y: rotatedSize.height/2.0) 
      context.translateBy(x: origin.x, y: origin.y) 
      context.rotate(by: radians) 
      draw(in: CGRect(x: -origin.x, y: -origin.y, width: size.width, height: size.height)) 
      let rotatedImage = UIGraphicsGetImageFromCurrentImageContext() 
      UIGraphicsEndImageContext() 

      return rotatedImage ?? self 
     } 

     return self 
    } 
} 

Aby wykonać obrót o 180 stopni, można nazwać tak:

let rotatedImage = image.rotate(radians: .pi) 

jeżeli z jakiegokolwiek powodu nie powiedzie się obracać, oryginalny obraz zostanie zwrócony.