web-dev-qa-db-fra.com

Comment faire pivoter l'image dans Swift?

Je ne parviens pas à faire pivoter l'image de 90 degrés avec Swift. J'ai écrit ci-dessous le code mais il y a une erreur et ne compile pas

  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

  }

ci-dessous est le code que je ne suis pas sûr de

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))
41
Dhiraj Kumar

Ceci est une extension de UIImage qui cible Swift 4. et peut faire pivoter uniquement l'image sans avoir besoin d'un UIImageView. Testé avec succès que l'image a été pivotée, et pas seulement ses données exif ont été modifiées.

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.y, y: -Origin.x,
                            width: size.width, height: size.height))
            let rotatedImage = UIGraphicsGetImageFromCurrentImageContext()
            UIGraphicsEndImageContext()

            return rotatedImage ?? self
        }

        return self
    }
}

Pour effectuer une rotation de 180 degrés, vous pouvez l'appeler comme suit:

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

Si, pour une raison quelconque, la rotation n’est pas effectuée, l’image d’origine sera alors renvoyée.

14
CodeBender

définir l'image ImageView

ImageView.transform = ImageView.transform.rotated(by: CGFloat(M_PI_2))
55
Jayesh Miruliya
 let angle =  CGFloat(M_PI_2)
  let tr = CGAffineTransform.identity.rotated(by: angle)
  ImageView.transform = tr
18
Chirag kukreja

En une ligne:

rotatedViewBox.transform = CGAffineTransform(rotationAngle: CGFloat.pi/2)
15
Aaron Halvorsen

Dans Swift 4.2 et Xcode 10.0

dropDownImageView.transform = dropDownImageView.transform.rotated(by: CGFloat(Double.pi / 2))

Si vous voulez ajouter une animation ...

UIView.animate(withDuration: 2.0, animations: {
   self.dropDownImageView.transform = self.dropDownImageView.transform.rotated(by: CGFloat(Double.pi / 2))
})
11
iOS

Vous pouvez utiliser le code ci-dessous pour 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
}
6
Smit Yash

Vous pouvez d'abord définir votre image dans imageView et faire pivoter pour obtenir votre image dans imageView

Ici:

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!
2
Okan

Votre code n'est pas si loin d'être fonctionnel. Vous pouvez appliquer la transformation comme vous le faites directement au bitmap, vous n'avez pas besoin d'une vue intermédiaire:

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
}

En outre, si vous créez une fonction qui fait pivoter une image, il est généralement judicieux d'inclure un paramètre clockwise: Bool qui interprétera l'argument degrees comme une rotation dans le sens des aiguilles d'une montre ou non. La mise en œuvre et la conversion appropriée en radians je vous laisse.

Notez aussi que c'est un peu vague de ma part de supposer que oldImage.size est différent de zéro. Si tel est le cas, le décompressage forcé UIGraphicsGetCurrentContext()! se produira probablement. Vous devez valider la taille de oldImage et, si elle est invalide, vous devez simplement renvoyer oldImage.

1
par

Votre problème est que vous utilisez un initialiseur non existant pour CGRect. Si vous souhaitez utiliser CGRect (Origin: size:), créez correctement Origin, sans paramètres de largeur et de hauteur. Ou supprimez le paramètre de taille et utilisez CGRect (x: y: largeur: hauteur:).

Il suffit de remplacer cette ligne

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

avec celui-ci:

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