iT邦幫忙

2021 iThome 鐵人賽

DAY 19
0
自我挑戰組

一個令我自豪的App完成之路系列 第 19

AVFoundation 來看看 Day 19

在第17天,做了一個ISBN 查詢 書本的書名、書本描述

那麼今天我希望做一個使用拍照掃描辨識出ISBN碼,這樣就不用手動輸入ISBN碼

使用Vision套件

import Vision

主要是透過apple 發布的Vision套件來辨識

透過Vision套件來做也需要一個相機的View來使用Vision套件

今天先來使用建立相機View

使用AVFoundation套件來建立相機View

// 使用AVFoundation建立相機View
import AVFoundation

https://i.imgur.com/1lJ9KxX.png

  • AVCaptureSession:AVFoundation的核心,用來Capture跟Coordinate Data flow
  • AVCaptureDevice:獲得硬體設備
  • AVCapturePhotoOutput: Photo的輸出
  • AVCaptureVideoPreviewLayer:Preview的Layer

使用的三個func來建構

  • checkPermission():來確保相機都是可以使用的
  • ConfigLiveView():來設定好相機以及資料流
  • addButton():新增拍攝Button進入View
func checkPermission(){
	let mediaType = AVMediaType.video
	// authorizationStatus回傳一個常數看是否能夠使用某個(mediaType)類型
	let status = AVCaptureDevice.authorizationStatus(for: mediaType)
	
	switch status{
		case .denied,.restricted:
			// 如果不能使用,則會出現提示來要求權限
			let Noauthorized = UIAlertController(title:"Error", message: "", preferredstyle: .alert)
			Noauthorized.addAction(UIAlertAction(title:"Set", style: .default){
							let setting = URL(string:UIApplication.openSettingsURLString)!
							UIApplication.shared.open(setting)
							}
		default:
			break

		}

}

ConfigLiveView(){

func ConfigLiveView(){
	// 最重要的部分,Session負責管理Capture & DataFlow
	captureSession = AVCaptureSession()
	// 規範Capture的資料要是什麼解析度
	captureSession.sessionPresent = .hd1920x1080

	// 開始Capture Device 
	// 使用DiscoverySession來將符合資料的Device資料儲存
	let deviceDiscoverySession = AVCaptureDevice.DiscoverytSession(deviceTypes:[AVCaptureDevice.DeviceType.builtInDualCamera],mediaType:AVMediaType.video, position: .back)
	
	// 所有符合資料的Device
	let devices = deviceDiscoverySession.devices
	for device in devices{
		if device.position == AVCaptureDevice.Postion.back{
				// 將符合資料的儲存進backCamera內
				backCamera = device
		}
	}

// 設定Input & Output
	do{
		// 讓AVCaptureDeviceInput類的資料為backCamera儲存至captureDeviceInput
		let captureDeviceInput = try AVCaptureDeviceInput(device:backCamera)
		captureSession.addInput(captureDeviceInput)
		}catch{
			showAlert(withTitle:"Camera Error")
			return
		}
	catureOutput = AVCapturePhotoOutput()
	// 設定好拍攝設定
	captureOutput?.setPreparedPhotoSettingsArray([AVCapturePhotoSetting(format:[AVVideoCodeKey:AVVideoCodecType.jpeg)
	captureSession.addOuptut(captureOutput!)

// 增加Preview Layer
	cameraPreviewLayer = AVCaptureVideoPreviewLayer(session:captureSession)
	cameraPreviewLayer?.videoGravity = .resizeAspectFill
	cameraPreviewLayer?.connection.videoOrientation = .portrait
	cameraPreviewLayer?.frame = view.frame
// The sublayer to be inserted into the current layer.
	self.view.layer.insertlayer(cameraPreviewLayer!,at:0)

	captureSession.startRunning()

}

addButton()

func addButton(){

	let width:CGFloat = 75
	let height = width
	button = UIButton(frame:CGRect(x: (view.frame.width - width)/2, y: view.frame.height - height - 32, width: width, height: height))
	button.backgroundColor = UIColor.white
	button.showsTouchWhenHighlighted = true
	button.addTarget(self,action: #selector(captureImage), for: .touchUpInside)
	view.addSubView(button)
}

captureImage() 用來Capture照片

// Capture
@objc func captureImage(){
	let setting = AVCapturePhotoSettings()
	captureOutput?.capturePhoto(with:setting, delegate: self)
}
	

showAlert() 用來作為提示用

func showAlert(withTitle: String){
	let UIAlertController(title:withTitle, message:"", preferredStyle: .alert)
	alertController.addAction(UIAlertAction(title:"OK", style: .default, handler:nil))
	present(alertController,animated:true,completion:nil)
}

參考網址:

程式碼都是參考自

Github

加上了一點自己DIY的理解

iOS AVCaptureSession学习笔记(一)

Apple Developer Documentation

iOS拍照定制之AVCapturePhotoOutput

Apple Developer Documentation
Apple Developer Documentation


上一篇
UISearchController 出來挑土豆 Day 18
下一篇
ISBN Barcode Scanner實作 Day 20
系列文
一個令我自豪的App完成之路32
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言