vaguely

和歌山に戻りました。ふらふらと色々なものに手を出す毎日。

Swift + OpenCV

前回作成したサンプルを、そのままSwiftに置き換えてみたメモ。

準備

とりあえずXcode6 Beta6をインストールしたところ、Xcode自体は起動するものの、なぜかSimulatorが起動せず、エラーに。

ネットで調べつつ色々試したものの、結局Macを再起動したら問題なく動作するようになりました。

プロジェクトの作成はObjective-Cと同じで、言語をSwiftにするだけです。

opencv2.frameworkも同じように追加します。

SwiftObjective-Cの振り分け

Storyboardを使ったUI部分や、UIImageを使用する部分はSwiftで記述することにします。

しかし、SwiftにはCやC++との互換性がないため、C++を使用するOpenCVを扱う部分はObjective-Cで記述します。

Swift

Delegate、ViewControllerのファイルが.hと.mの2つではなく、.swift一つになったことを除けばほぼObjective-Cと同じように作成できます。

Delegateは特に触っていないので、ViewControllerについてのみまとめます。

ViewController.swift

import UIKit

class ViewController: UIViewController {
                            
    @IBOutlet weak var imgImageView: UIImageView!
    @IBOutlet weak var btnColor: UIButton!
    @IBOutlet weak var btnGray: UIButton!
    @IBOutlet weak var btnThreshold: UIButton!
    @IBOutlet weak var btnSobel: UIButton!
    @IBOutlet weak var btnSave: UIButton!
    
    var imgCurrent:UIImage?
    let strImageUrl:NSString = "https://joindiaspora.s3.amazonaws.com/uploads/images/scaled_full_1081a16e63283b49bfab.jpg"
    // OpenCV操作クラス
    let imgController:ImageController = ImageController()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        var imgSource:UIImage = UIImage(data: NSData(contentsOfURL: NSURL(string: strImageUrl)))
        
        // 初期化及び画像の操作
        imgController.initOpenCv(imgSource)
        // デフォルトでColor画像を表示する
        self.setImgColorAsCurrent()
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
    func setImgColorAsCurrent()
    {
        imgCurrent = imgController.getImgColor()
        self.updateImageViewer()
    }
    func updateImageViewer()
    {
        imgImageView.image = imgCurrent
    }
    @IBAction func btnColorTouched(sender: UIButton) {
        imgCurrent = imgController.getImgColor()
        self.updateImageViewer()
    }
    @IBAction func btnGrayTouched(sender: UIButton) {
        imgCurrent = imgController.getImgGray()
        self.updateImageViewer()
    }

    @IBAction func btnThresholdTouched(sender: UIButton) {
        imgCurrent = imgController.getImgThreshold()
        self.updateImageViewer()
    }
    @IBAction func btnSobelTouched(sender: UIButton) {
        imgCurrent = imgController.getImgSobel()
        self.updateImageViewer()
    }
    @IBAction func btnSaveTouched(sender: UIButton)
    {
        // Albumに画像を保存する
        UIImageWriteToSavedPhotosAlbum(imgCurrent, self, Selector("onSavedImage:error:contextInfo:"), nil)
    }
    func onSavedImage(image: UIImage!, error: NSErrorPointer, contextInfo: UnsafePointer<()>)
    {
        let alrShowMessage:UIAlertView = UIAlertView(title: "Finished", message: "保存しました", delegate: nil, cancelButtonTitle: "OK")
        
        alrShowMessage.show()
    }
}

変数

var 変数名: 型名 で変更可能な変数が、let 変数名: 型名 で変更不可能な変数を作成できます。

この際、デフォルトの値を設定しないで[var img: UIImage]のようにするとエラーとなります。

エラーがクラス名のところで表示されるので驚きましたが...。

[var img: UIImage?]または[var img: UIImage!]とすることでエラーを解消できます。

画像の保存

Objective-Cと同じくUIImageWriteToSavedPhotosAlbumで保存ができるのですが、保存後実行するメソッドを設定していた@Selectorがありません。

上記コード内では[Selector("onSavedImage:error:contextInfo:")]としていますが、単純に["onSavedImage:error:contextInfo:"]としても問題ありませんでした。

Objective-Cについては次回。

参考