swift言語: AVFoundationを使ってQRCodeReaderを作成してみました
概要
QRCode Reader Using Swift Tutorialを参考に、AVFoundationを使ってQRCodeReaderを作成してみました。
QRコード読取処理のライブラリ化を行いながら、AV Foundationについてもう少し調べていく予定です。
AV Foundation
AVFoundationは、時間ベースのオーディオビジュアルメディアの再生と作成に使用できるフレーム ワークで、時間ベースのオーディオビジュアルデータに関する作業を細かいレベルで行うための インターフェイスを提供します。詳細は、以下を参照してください。
- AV Foundation for iOS and OS X - Apple Developer
- About AVFoundation
- AVFoundationプログラミングガイド
- AVCam-iOS: Using AVFoundation to Capture Images and Movies
AV Foundationの各クラスの説明が、以下にあります。 AV Foundation Framework Reference
AVFoundationのswift実装については、以下のページが参考になります。 AVFoundation Changes for Swift
実装
以下の手順で実装します。
セッションを作成します
キャプチャデバイスを探し、セッションを作成します。
参考。
- AVCaptureDevice Class Reference
- AVCaptureDeviceInput Class Reference
- AVCaptureSession Class Reference
func configureVideoCapture() -> AVCaptureSession? {
do {
let captureDevice = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeVideo)
let deviceInput = try AVCaptureDeviceInput(device: captureDevice) as AVCaptureDeviceInput
let session = AVCaptureSession()
session.addInput(deviceInput as AVCaptureInput)
let metadataOutput = AVCaptureMetadataOutput()
session.addOutput(metadataOutput)
metadataOutput.setMetadataObjectsDelegate(self, queue: dispatch_get_main_queue())
metadataOutput.metadataObjectTypes = [AVMetadataObjectTypeQRCode]
return session
} catch let error as NSError {
let alertController: UIAlertController = UIAlertController(title: "Device Error", message: error.localizedFailureReason, preferredStyle: .Alert)
let defaultAction = UIAlertAction(title: "OK", style: .Default, handler: nil)
alertController.addAction(defaultAction)
presentViewController(alertController, animated: true, completion: nil)
}
return nil
}
VideoPreviewLayerを作成します
キャプチャしている画像を表示するPreviewLayperを作成します。
参考。
func createVideoPreviewLayer(session: AVCaptureSession) -> AVCaptureVideoPreviewLayer? {
let captureVideoPreviewLayer = AVCaptureVideoPreviewLayer(session: session)
if let preview = captureVideoPreviewLayer {
preview.videoGravity = AVLayerVideoGravityResizeAspectFill
preview.frame = view.layer.bounds
return preview
}
return nil
}
delegateメソッド実装
AVCaptureMetadataOutputObjectsDelegateプロトコルを実装する必要があります。
func captureOutput(captureOutput: AVCaptureOutput!, didOutputMetadataObjects metadataObjects: [AnyObject]!, fromConnection connection: AVCaptureConnection!) {
if metadataObjects == nil || metadataObjects.count == 0 {
didnotDetectQRCode();
return
}
let metadata: AVMetadataMachineReadableCodeObject = metadataObjects[0] as! AVMetadataMachineReadableCodeObject
didFindQRCode(metadata)
}
func didnotDetectQRCode() {
qrcodeView!.frame = CGRectZero
print("NO QRCode text detacted")
}
func didFindQRCode(metadata: AVMetadataMachineReadableCodeObject) {
if metadata.type == AVMetadataObjectTypeQRCode {
let barCode = captureVideoPreviewLayer!.transformedMetadataObjectForMetadataObject(metadata) as! AVMetadataMachineReadableCodeObject
qrcodeView!.frame = barCode.bounds;
if metadata.stringValue != nil {
qrcodeView!.frame = CGRectZero
let result = metadata.stringValue
print(result)
self.label.text = result
self.captureVideoPreviewLayer!.removeFromSuperlayer()
self.captureSession!.stopRunning()
}
}
}
UI作成
QRコードを囲むUIViewを作成します。
func createQRView() -> UIView {
let view = UIView()
view.layer.borderColor = UIColor.redColor().CGColor
view.layer.borderWidth = 5
return view
}
scanボタン作成。
QRコード読取を開始するUIButtonを作成します。UIButtonクリックイベントに以下の処理を追加します。
@IBAction func doScan(sender: UIBarButtonItem) {
self.captureSession = self.configureVideoCapture()
if let session = self.captureSession {
self.captureVideoPreviewLayer = self.createVideoPreviewLayer(session)
if let preview = captureVideoPreviewLayer {
self.view.layer.addSublayer(preview)
session.startRunning()
let view = self.createQRView()
self.view.addSubview(view)
self.view.bringSubviewToFront(view)
self.qrcodeView = view
}
}
}
ソースコード
関連資料
- QRCode Reader Using Swift Tutorial
- AV Foundation for iOS and OS X - Apple Developer
- About AVFoundation
- AVFoundationプログラミングガイド
- AVCam-iOS: Using AVFoundation to Capture Images and Movies
- AVFoundation Changes for Swift
- AV Foundation Framework Reference
- AVCaptureDevice Class Reference
- AVCaptureDeviceInput Class Reference
- AVCaptureSession Class Reference
- AVCaptureVideoPreviewLayer Class Reference