やりたいこと
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
の回転をしてみた結果、、
回転後も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
}
}
画像のサイズを指定する際に、
CGRect(origin: .zero, size: self.size).applying(CGAffineTransform(rotationAngle: radian))
というように回転のTransformを適応した後のCGRect
を作成し、そのサイズで画像を作成するようにしています。
※Playground上での表示ではサイズが同じに見えますが、回転後のUIImage
は元の画像の部分の大きさが同じサイズで、UIImage
としてのサイズは大きくなっています。
余談
-
UIGraphicsBeginImageContext
はUIGraphicsBeginImageContextWithOptions
をお使いください。 - 切り抜きって、「clip」でしょうか「crop」でしょうか、、?
最後に
もっといい方法があればご教授ください。