1. ryokosuge

    Posted

    ryokosuge
Changes in title
+UIImageの加工について
Changes in tags
Changes in body
Source | HTML | Preview
@@ -0,0 +1,127 @@
+## iOS その3 Advent Calendar
+
+3日目を書かせていただきます!
+
+今年は何記事書けるのかな...。
+
+**iOS**ということでSwiftのことではなく**UIKit**周りのことを書ければと思います。
+
+といことで早速本題です。
+
+## UIImageの加工
+
+先日作成したアプリで(S3とかにある)画像をたくさん並べる処理をして、案の定**スクロールがカクツク問題**にぶち当たりました。
+
+その際に色々試した**UIImageの加工**について紹介します。
+
+## 紹介する処理
+
+- リサイズ
+ - 比率を保たない
+ - 比率を保つ
+- 角丸
+- ボーダー
+
+あたりを紹介できればと思います。
+
+## リサイズ
+
+```swift:UIImage+resize.swift
+extension UIImage {
+
+ // 比率保つ版
+ func resize(_ size: CGSize) -> UIImage? {
+ let widthRatio = size.width / self.size.width
+ let heightRatio = size.height / self.size.height
+ let ratio = (widthRatio < heightRatio) ? widthRatio : heightRatio
+ let resizedWidth = round(self.size.width * ratio)
+ let resizedHeight = round(self.size.height * ratio)
+ let resizedSize = CGSize(width: resizedWidth, height: resizedHeight)
+ UIGraphicsBeginImageContextWithOptions(resizedSize, false, UIScreen.mainScreen().scale)
+ let drawRect = CGRect(origin: CGPointZero, size: resizedSize)
+ drawInRect(drawRect)
+ let resizedImage = UIGraphicsGetImageFromCurrentImageContext()
+ UIGraphicsEndImageContext()
+ return resizedImage
+ }
+
+ // 比率保たない版
+ func resize(_ size: CGSize) -> UIImage? {
+ UIGraphicsBeginImageContextWithOptions(size, false, UIScreen.mainScreen().scale)
+ let drawRect = CGRect(origin: CGPointZero, size: resizedSize)
+ drawInRect(drawRect)
+ let resizedImage = UIGraphicsGetImageFromCurrentImageContext()
+ UIGraphicsEndImageContext()
+ return resizedImage
+ }
+}
+```
+
+注意点は特にありません...。
+
+## 角丸
+
+```swift:UIImage+maskCorner.swift
+extension UIImage {
+ func maskCorner(radius r: CGFloat) -> UIImage? {
+ UIGraphicsBeginImageContextWithOptions(self.size, false, UIScreen.mainScreen().scale)
+
+ let rect = CGRect(origin: CGPointZero, size: self.size)
+ UIBezierPath(roundedRect: rect, cornerRadius: r).addClip()
+ drawInRect(rect)
+ let clippedImage = UIGraphicsGetImageFromCurrentImageContext()
+
+ UIGraphicsEndImageContext()
+ return clippedImage
+ }
+}
+```
+
+注意点は特にありません...。
+
+## ボーダー
+
+```swift:UIImage+drawBorder.swift
+extension UIImage {
+
+ func drawBorder(width borderWidth: CGFloat, color: UIColor) -> UIImage? {
+
+ UIGraphicsBeginImageContextWithOptions(size, false, UIScreen.mainScreen().scale)
+
+ // clip corner
+ let rect = CGRect(origin: CGPointZero, size: self.size)
+
+ let context = UIGraphicsGetCurrentContext()
+ CGContextSaveGState(context!)
+
+ drawInRect(rect)
+ CGContextRestoreGState(context!)
+
+ let insetRect = CGRectInset(rect, borderWidth / 2.0, borderWidth / 2.0)
+ let path = UIBezierPath(rect: insetRect)
+ color.setStroke()
+ path.lineWidth = borderWidth
+
+ path.stroke()
+
+ let image = UIGraphicsGetImageFromCurrentImageContext()
+ UIGraphicsEndImageContext()
+ return image
+ }
+
+}
+```
+
+## 補足
+
+ちなみにこの**UIImageの加工の処理**は**メインスレッド以外**でも実行できます。
+
+なので**UICollectionViewCell**などで**SDWebImage**と一緒に使う場合はダウンロード処理が終わった後Cellのサイズに合わせてリサイズした後に表示処理をするとスクロールの邪魔もしづらくなります。(個人の体感ですが...)
+
+## 終わりに
+
+**UICollectionViewCell**の*layer*をいじるよりだいぶ邪魔しないで済む方法になるかと思います。
+
+ただ、もしできることならS3などの画像をリクエストでリサイズできるようお願いするともっと幸せになれるかもしれないです。
+
+以上になります。