web-dev-qa-db-ja.com

Swiftで画像を回転させる方法は?

Swiftで画像を90度回転させることができません。私は以下のコードを書きましたが、エラーがあり、コンパイルしません

  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

  }

以下は私がわからないコードです

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

これは、Swift 4.をターゲットとするUIImageの拡張であり、UIImageViewを必要とせずにイメージのみを回転できます。 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.y, y: -Origin.x,
                            width: size.width, height: size.height))
            let rotatedImage = UIGraphicsGetImageFromCurrentImageContext()
            UIGraphicsEndImageContext()

            return rotatedImage ?? self
        }

        return self
    }
}

180度の回転を実行するには、次のように呼び出すことができます。

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

何らかの理由で回転に失敗した場合、元の画像が返されます。

14
CodeBender

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

1行で:

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

Swift 4.2およびXcode 10.0

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

アニメーションを追加する場合...

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

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

最初にimageViewで画像を設定し、imageViewで画像を回転して取得できます。

ここに:

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

あなたのコードは機能的からそう遠くありません。ビットマップに直接行うように変換を適用できます。中間ビューは必要ありません。

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
}

また、画像を回転させる関数を作成する場合、通常、degrees引数を時計回りに回転するかどうかを解釈するclockwise: Boolパラメーターを含めるのが適切です。実装とラジアンへの適切な変換はあなたにお任せします。

また、oldImage.sizeがゼロ以外であると仮定することは、私の側では少し手作業であることに注意してください。そうである場合、UIGraphicsGetCurrentContext()!を強制的にアンラップすると、おそらくクラッシュします。 oldImageのサイズを検証し、無効な場合はoldImageを返す必要があります。

1
par

問題は、CGRectに存在しない初期化子を使用することです。 CGRect(Origin:size:)を使用する場合は、幅と高さのパラメーターを指定せずにOriginを適切に作成します。または、サイズパラメータを削除してCGRect(x:y:width:height:)を使用します。

この行を置き換えるだけです

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