LoginSignup
19
16

More than 5 years have passed since last update.

【Swift】切り抜かずにUIImageを回転させる

Posted at

やりたいこと

こういうUIImageから
image.jpg

こういうUIImageに加工したい
tmp2.jpeg

UIImageを回転させる

まずは先人のお知恵を拝借しようとググってみると、だいたい下のようなコードが見つかりました。
(ググってすぐに出てくるのはありがたい!!)


extension UIImage {

    func rotatedBy(degree: CGFloat) -> UIImage {
        let radian = -degree * CGFloat.pi / 180
        UIGraphicsBeginImageContext(self.size)
        let context = UIGraphicsGetCurrentContext()!
        context.translateBy(x: self.size.width / 2, y: self.size.height / 2)
        context.scaleBy(x: 1.0, y: -1.0)

        context.rotate(by: radian)
        context.draw(self.cgImage!, in: CGRect(x: -(self.size.width / 2), y: -(self.size.height / 2), width: self.size.width, height: self.size.height))

        let rotatedImage = UIGraphicsGetImageFromCurrentImageContext()!
        UIGraphicsEndImageContext()
        return rotatedImage
    }

}

やってることはこちらの記事の説明が図解付きでわかりやすかったです。

上記のコードを使ってUIImageの回転をしてみた結果、、

このようになりました。
スクリーンショット 2018-02-09 19.20.07.png

回転後もUIImageのサイズは変わらないため、回転してはみ出した部分が切り取られてしまいますね。
今回は回転して切り取られないようにしたいので、もう一手間加えてみました。

完成コード


extension UIImage {

    func rotatedBy(degree: CGFloat, isCropped: Bool = true) -> UIImage {
        let radian = -degree * CGFloat.pi / 180
        var rotatedRect = CGRect(origin: .zero, size: self.size)
        if !isCropped {
            rotatedRect = rotatedRect.applying(CGAffineTransform(rotationAngle: radian))
        }
        UIGraphicsBeginImageContext(rotatedRect.size)
        let context = UIGraphicsGetCurrentContext()!
        context.translateBy(x: rotatedRect.size.width / 2, y: rotatedRect.size.height / 2)
        context.scaleBy(x: 1.0, y: -1.0)

        context.rotate(by: radian)
        context.draw(self.cgImage!, in: CGRect(x: -(self.size.width / 2), y: -(self.size.height / 2), width: self.size.width, height: self.size.height))

        let rotatedImage = UIGraphicsGetImageFromCurrentImageContext()!
        UIGraphicsEndImageContext()
        return rotatedImage
    }

}

こんな感じですね。
スクリーンショット 2018-02-09 23.36.35.png

画像のサイズを指定する際に、

CGRect(origin: .zero, size: self.size).applying(CGAffineTransform(rotationAngle: radian))

というように回転のTransformを適応した後のCGRectを作成し、そのサイズで画像を作成するようにしています。

※Playground上での表示ではサイズが同じに見えますが、回転後のUIImageは元の画像の部分の大きさが同じサイズで、UIImageとしてのサイズは大きくなっています。

余談

  • UIGraphicsBeginImageContextUIGraphicsBeginImageContextWithOptionsをお使いください。
  • 切り抜きって、「clip」でしょうか「crop」でしょうか、、?:thinking:

最後に

もっといい方法があればご教授ください。:bow_tone1:

19
16
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
19
16