Created
February 20, 2019 08:12
-
-
Save PattyAppier/a2440bbf48d5ae8864930d994572db35 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ViewController.swift | |
// PattyScanner | |
// Created by PattysiChip on 2019/2/20. | |
// Copyright © 2019 PattysiChip. All rights reserved. | |
import UIKit | |
import AVFoundation | |
import CoreGraphics | |
// AVCaptutureMetadataOutput 是 Read barcode 的核心,能夠 intercept 攔截來自輸入裝置的原資料。 | |
// 此協定能讓元資料被擷取時,將其轉給代理 self 操作。 | |
class ViewController: UIViewController, AVCaptureMetadataOutputObjectsDelegate { | |
// ? 可為 nil, ! 不可為 nil | |
var captureSession: AVCaptureSession? //AVcaptureSession 用來協調自影像輸入裝置至輸出的資料流程 | |
var videoPreviewLayer: AVCaptureVideoPreviewLayer? | |
var qrCodeFrameView: UIView? | |
// AVCaptureDevice 代表一個擷取裝置,能藉由其方法控制手機底層屬性。 | |
override func viewDidLoad() { | |
let captureDevice = AVCaptureDevice.default(for: AVMediaType.video) // 取得影像中的截圖實體 | |
var error: NSError? | |
let input: AnyObject! = AVCaptureDeviceInput.deviceInputWithDevice(captureDevice, error: error) // 繼承 &error? ///////// | |
if(error != nil) { | |
print("\(String(describing: error?.localizedDescription))") | |
/////////BUG | |
// 錯誤產生,則紀錄狀態,並且返回 | |
return | |
} | |
// 為何此容器沒有設定為變數或是常數??? | |
captureSession = AVCaptureSession() // AVcaptureSession 用來協調自影像輸入裝置至輸出的資料流程 | |
captureSession?.addInput(input as! AVCaptureInput) // 設定輸入裝置, as||as! | |
//AVCaptutureMetadataOutput 是 Read barcode 的核心,能夠 intercept 攔截來自輸入裝置的原資料。 | |
let captureMetadataOutput = AVCaptureMetadataOutput() | |
captureSession?.addOutput(captureMetadataOutput) | |
// 參數1 直接不繼承,改採 self; 參數2 佇列使用串列佇列,採用如下函數來指定調度佇列代替類別 DispatchQueue,取得預設得串列佇列。 | |
var dispatchQ: DispatchQueue = 00000000 | |
// 常樹和變數,我暫時定為變數,預設為數子八個零 ////////BUG | |
captureMetadataOutput.setMetadataObjectsDelegate(self, queue: dispatchQ) | |
captureMetadataOutput.metadataObjectTypes = [AVMetadataObject.ObjectType.qr] | |
//藉由初始化,做出預覽層, | |
//並藉由方法 addSubLayer 加入 AVCaptureVideoPreviewLayer 型別的值作為 view 視圖層的子層 | |
let defautMetaData = AVCaptureSession() | |
videoPreviewLayer = AVCaptureVideoPreviewLayer(session: captureSession ?? defautMetaData); | |
videoPreviewLayer?.videoGravity = AVLayerVideoGravity.resizeAspectFill | |
videoPreviewLayer?.frame = view.layer.bounds | |
view.layer.addSublayer(videoPreviewLayer ?? defautMetaData as! CALayer) | |
////////// | |
//擷取影像,用以捕捉影像,然而還沒將訊息標籤做出來喔 | |
var messageLabel: UILabel // to get member of "text", change type from UIView to UILabel | |
captureSession?.startRunning() | |
view.bringSubviewToFront(messageLabel) | |
//提取元資料,此方法能解碼 | |
func captureOutput(_captureOutput: AVCaptureOutput!, didOutputMetadataObjects metadataObjects: [AnyObject]!, fromConnection connection: AVCaptureConnection!) { | |
if metadataObjects == nil || metadataObjects.count == 0 { | |
qrCodeFrameView?.frame:CoreGraphics.CGRect | |
// 要追加 init 框框嗎? //////////// BUG | |
messageLabel.text = "No QR code is detected." | |
return | |
} | |
//取出元資料 | |
// meatadataObj 適合用變數還是常數? | |
var metadataObj = metadataObjects[0] as! AVMetadataMachineReadableCodeObject | |
if metadataObj.type == AVMetadataObject.ObjectType.qr { | |
//偵測二維碼的邊界 | |
let barCodeObject = videoPreviewLayer?.transformedMetadataObject(for: metadataObj as AVMetadataMachineReadableCodeObject) as! AVMetadataMachineReadableCodeObject | |
//設定綠色框框的大小,並且確保陣列型態的元資料不為空值,倘若為空值,則最好重置 qrCodeFrameView 可為零 | |
//配合 messageLabel 為預設訊息。 | |
qrCodeFrameView?.frame = barCodeObject.bounds; | |
if metadataObj.stringValue != nil { | |
messageLabel.text = metadataObj.stringValue | |
} | |
} | |
} | |
qrCodeFrameView?.frame = barCodeObject.bounds | |
///////////BUG | |
super.viewDidLoad() | |
// Do any additional setup after loading the view, typically from a nib. | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment