質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

87.58%

Swiftで通常の写真を→モノクロ写真へと変えるアプリを作りたい

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 2,730

score 199

前提・実現したいこと

「モノクロ」ボタンを押して画像をモノクロにする

発生している問題・エラーメッセージ

libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb)

発生している問題・エラーメッセージ

class AppDelegate: UIResponder, UIApplicationDelegate {


Thread 1:signal SIGABRT

該当のソースコード

import UIKit

class ViewController: UIViewController , UIImagePickerControllerDelegate, UINavigationControllerDelegate {

    @IBOutlet weak var imageView: UIImageView!

//    var originalImage: UIImage?

     //画像を編集するために画像を保持しておく変数
   var originalImage: UIImage?




    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
    }


    @IBAction func handleTap(sender: UITapGestureRecognizer) {

        if UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceType.PhotoLibrary) {
            let  ipc:UIImagePickerController = UIImagePickerController();
            ipc.delegate = self

            //sourceTypeってなんすか??
            ipc.sourceType = UIImagePickerControllerSourceType.PhotoLibrary


            //presentViewControllerってなんすか??
            self.presentViewController(ipc, animated: true, completion: nil)
        }

    }




    //ImagePickerで画像が選択されたときに呼ばれる

    func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {
        if info [UIImagePickerControllerOriginalImage] != nil {

            //選択した画像を UIImageViewに設定する
            imageView.image = info[UIImagePickerControllerOriginalImage] as? UIImage

            //加工用にメンバ変数に保持
            originalImage = info[UIImagePickerControllerOriginalImage]as? UIImage
        }

        //Imageviewを閉じる
        picker.dismissViewControllerAnimated(true, completion: nil)
    }


    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    // モノクロボタンが押された時に呼ばれる
    @IBAction func pushedMonochrome(sender: UIButton) {

        guard let image = imageView.image else {

            return
        }

        let monochroImage = monochromeImages(image)

        imageView.image = monochroImage
        originalImage = monochroImage

    }

    //引数のUIImage の画像をモノクロ化した UIImageを返す
    func monochromeImages (srcImage: UIImage) -> UIImage {
    //どうしてpushedMonochromeの中に処理を書かないのだろう


        //UIImageからCIImageを作る
        let ciImage: CIImage  = CIImage(image:srcImage)!;

        //コンテキストを作成する
        let ciContext:CIContext = CIContext(options: nil)

        //フィルターを作成する
        let ciFilter:CIFilter = CIFilter(name: "CIMinimumComponent")!
        CIFilter.setValue(ciImage, forKey: kCIInputImageKey)

        //フィルターを通した画像を生成する
        let cgimg:CGImageRef = ciContext.createCGImage(ciFilter.outputImage!, fromRect: ciFilter.outputImage!.extent)!


        //CGImageRefからUIImageを作成して返す
        return UIImage(CGImage: cgimg, scale: 1.0, orientation: UIImageOrientation.Up)

    }

    // スライダーの値が変わった時に呼ばれる
    @IBAction func valueChanged(sender: UISlider) {

    }

    // 保存ボタンが押された時に呼ばれる
    @IBAction func save(sender: UIButton) {

    }
}

考えられる原因・アドバイス頂きたい点

ビルドは成功するのでソースコードにミスはない。しかし、「モノクロ」ボタンを押した途端に泊まるのでIBActionの中の処理か、IBActionで呼び出した関数の中の処理に問題があると思われる

Thread 1:signal SIGABRT というエラーはたまによく現れるが、具体的なエラーの内容がわかりにくいので、どのように考えるべきかアドバイス頂きたい。ネットで調べると「ストーリーボード上のミスがこのエラーの原因」だという説あり

また、右下のログに関しても、初期状態で「モノクロ」を押すと enable_private_data: 0というログが出るので動いてると思う。画像を選択した状態で「モノクロ」を押すとエラーになる。

だから、「もし関数に値が入ってなかったらreturn返す」という処理は呼ばれてるということになる。つまり、画像が変数に入った時に確実にエラーが発生している。

つまり、エラーが起きているのは、モノクロボタンを押された時に呼ばれるIBActionのところでもなく、IBActionの処理で呼ばれる画像をモノクロにして返すという処理でもないのではないか?もっと前でエラーが起こってるのではないか?

しかし、自分の知識ではここで思考が停止しました。

補足情報(言語/FW/ツール等のバージョンなど)

xcode8

swift2.3

githubにソースをすべて公開↓

https://github.com/Ryosuke-Hujisawa/Swift-2016-10-1

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

+1

こちらの環境がXcode7なので、細かいところで違いがあるかも知れません。(githubのプロジェクトも動かせません)

 どこで止まっているか調べる方法

  • Breakpoint Navigatorを表示する
  • 左下のを押して、Add Exception Breakpoint...を選択。設定(吹き出し)はデフォルトのままでいいので、そのまま閉じる。
  • 実行する。

 どこで止まっているか

CIFilter.setValue(ciImage, forKey: kCIInputImageKey)

ここ。

 どうすれば止まらなくなるか

ciFilter.setValue(ciImage, forKey: kCIInputImageKey)

こうする。上の行で生成したインスタンスにsetValueしないといけない。

 教訓

ビルドは成功するのでソースコードにミスはない。

そんなことはありません。
ビルド成功はスタート地点に過ぎません。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/10/04 11:17

    ありがとうございます。「ビルド成功はスタート地点」。教訓にします

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 87.58%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る