Swiftで画像の切り抜き

いわゆる、crop(クロップ)のこと。

Swiftだと、extensionが使えるので、UIImageを拡張して対応してみた。

こんな感じ。

extension UIImage {
    func cropImageWithRect(rect: CGRect) -> UIImage? {
        let left = rect.minX * self.scale
        let top = rect.minY * self.scale
        let w = rect.width * self.scale
        let h = rect.height * self.scale
        
        let cropRect = CGRect( origin: CGPoint(x: left, y: top), size: CGSize(width: w, height: h) )
        let cgImgRef = CGImageCreateWithImageInRect( self.CGImage, cropRect )
        return UIImage( CGImage: cgImgRef, scale: self.scale, orientation: .Up )
    }
}

たぶん、CoreGraphics.frameworkの追加が必要なんじゃないのかな?
あと、これを書いてて気付いたけど、画像の向きが.Upじゃない場合はどうしようね?

これを書いた目的だけど、
こんな感じでUISegmentedControlを初期化するのに書いた。

func initHogeSelector(target: UISegmentedControl) {
    let n = 3
    let largeImage = UIImage( named: "foo" )! // -> "foo.png"
    let iconWidth = largeImage.size.width / CGFloat(n)
    let iconHeight = largeImage.size.height
    let margin: CGFloat = 4.0

    var cropRect = CGRect( x: margin, y: margin, width: (iconWidth - margin - margin), height: (iconHeight - margin - margin) )
    target.removeAllSegments()
    for i in 0..<n {
        let img = largeImage.cropImageWithRect( cropRect )!.imageWithRenderingMode( .AlwaysTemplate )
        target.insertSegmentWithImage( img, atIndex: i, animated: false )

        cropRect.offset( dx: iconWidth, dy: 0.0 )
    }
}

イラストレーターを使うとスライスの書き出し機能があって、
その機能を使えば、切り抜いた状態で一括書き出しが出来るのだけど、
画像を更新する手間を考えるとファイル数が少ない方が楽なので、
アイコンを連結した状態で書き出して、コードでなんとかすることにした。

ところで、extensionを使う場合って、
適当なファイルを用意して、そこに記述すると思うんだけど、
なんてファイル名にするのがSwiftマナーなんですかね?

今回は、こちらを参考にさせて頂きました。
http://blog.k-jee.com/2010/01/uiimagehow-to-crop-uiimage.html

おしまい。

Leave a Comment