Skip to content

Instantly share code, notes, and snippets.

@PattyAppier
Created February 20, 2019 08:12
Show Gist options
  • Save PattyAppier/a2440bbf48d5ae8864930d994572db35 to your computer and use it in GitHub Desktop.
Save PattyAppier/a2440bbf48d5ae8864930d994572db35 to your computer and use it in GitHub Desktop.
// 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