Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // 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.
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement