![[iOS 8]CIQRCodeFeatureを使って画像からQRコードを解析する](https://devio2023-media.developers.io/wp-content/uploads/2014/06/ios81.png)
[iOS 8]CIQRCodeFeatureを使って画像からQRコードを解析する
この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
はじめに
QRコードを検出するCIQRCodeFeatureが新しくiOS8から追加されたので試してみました。
今回は下記のアプリを作ってみたいと思います。
| 写真をライブラリから読み込む ↓ 写真にQRコードがあるかCIQRCodeFeatureで解析する ↓ 見つけたらテキストに表示する | 
実装
画面構成
プロジェクトはSingleViewApplicationで作成します。 そして、storyboardは下図のように配置しました。
ViewController.swift に UIImageView、UITextViewのアウトレットを設定します。

また、ボタンのアクションも登録します。
これで下準備はOKです。
ソースコード
import UIKit
class ViewController: UIViewController, UINavigationControllerDelegate, UIImagePickerControllerDelegate {
    /** 写真表示用ImageView */
    @IBOutlet weak var photoImageView: UIImageView!
    /** QRコードの読取りテキストを表示 */
    @IBOutlet weak var messageTextView: UITextView!
    /** 画像取得用 */
    var picker:UIImagePickerController?
    /** 画像認識用 */
    var detector:CIDetector?
    
    override func viewDidLoad()
    {
        super.viewDidLoad()
        detector = CIDetector(ofType: CIDetectorTypeQRCode, context: nil, options: [CIDetectorAccuracy:CIDetectorAccuracyHigh])
        picker = UIImagePickerController()
        picker!.delegate = self
        picker!.allowsEditing = false
        messageTextView.resignFirstResponder()
    }
    /**
    * アルバムボタンをタップ
    */
    @IBAction func onTapAlbumButton(sender: AnyObject)
    {
        //ライブラリが使用できるかどうか判定
        if(UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceType.PhotoLibrary))
        {
            self.presentViewController(picker!, animated: true, completion: nil)
        }
    }
    /**
    * 写真選択
    */
    func imagePickerController(picker: UIImagePickerController!, didFinishPickingImage image: UIImage!, editingInfo: NSDictionary!){
        self.dismissViewControllerAnimated(true, completion: nil)
        //画面に写真を表示
        photoImageView.image = image
        //画像を変換
        var ciImage:CIImage = CIImage(image: image)
        var message:String = "";
        //画像内にQRコードがあるか調べる
        let features = detector?.featuresInImage(ciImage)
        for feature in features as [CIQRCodeFeature] {
            message += feature.messageString
        }
        //テキストに表示
        if(message == "") {
            messageTextView.text = "[QRコードは検出されませんでした]";
        } else {
            messageTextView.text = message;
        }
    }
    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
}
41行目でUIImageを画像処理用のCIImageに変換をします。
//画像を変換 var ciImage:CIImage = CIImage(image: image)
画像の種類については下記になります。
| UIImage : Viewとして表示するための画像クラス CIImage : CoreImageは画像処理のための画像クラス NSImage : Cocoaで画像データを扱う為のクラス CGImage : UIImageに含まれる | 
引用:http://qiita.com/oggata/items/8fc84124a256bfa505c0
そして、44行目で画像を渡し、QRコードが存在するか解析します。
//画像内にQRコードがあるか調べる
let features = detector?.featuresInImage(ciImage)
for feature in features as [CIQRCodeFeature] {
    message += feature.messageString
}
feature.messageStringにはQRコードの文字列が取得できます。 メッセージの他にも下記プロパティで位置や形なども取得できます。
| CIQRCodeFeature.bottomLeft CIQRCodeFeature.bottomRight CIQRCodeFeature.bounds CIQRCodeFeature.topLeft CIQRCodeFeature.topRight | 
実行結果について
無事、メッセージを読取る事が出来ました!
最後に
画像に対してQRコード自体が小さめでも読み込む事が出来き、以前より読み込み精度が上がっている印象を受けました。(あくまで、個人的な主観ですが。。。) CIFeatureには他にも画像の中の四角形を検出するCIRectangleFeatureが追加されています。 また、CIDetectorがシミュレーター上では動作しなかったので、実機で試す必要がありますのでご注意下さい。
















