Notice
Recent Posts
Recent Comments
Link
투케이2K
248. (ios/swift) AVCaptureSession , AVCaptureVideoPreviewLayer 사용해 카메라 QR 및 바코드 스캐너 만들기 본문
IOS
248. (ios/swift) AVCaptureSession , AVCaptureVideoPreviewLayer 사용해 카메라 QR 및 바코드 스캐너 만들기
투케이2K 2022. 11. 7. 12:18[개발 환경 설정]
개발 툴 : XCODE
개발 언어 : SWIFT
[사전 준비]
[호출 : 소스 코드]
// MARK: - [테스트 메인 함수 정의 실시]
func testMain() {
print("")
print("====================================")
print("[\(self.ACTIVITY_NAME) >> testMain() :: 테스트 함수 시작 실시]")
print("====================================")
print("")
/*
// -----------------------------
[요약 설명]
// -----------------------------
1. 사전 info plist 설정 :
Privacy - Camera Usage Description
// -----------------------------
2. 필요 import :
import AVKit
// -----------------------------
*/
// [비동기 처리 수행]
DispatchQueue.main.async {
// [카메라 사용 권한 확인]
let status = AVCaptureDevice.authorizationStatus(for: .video)
if (status == .authorized) {
print("")
print("====================================")
print("[\(self.ACTIVITY_NAME) >> testMain() :: 카메라 사용 권한 [허용] [1]]")
print("====================================")
print("")
DispatchQueue.main.async {
// [카메라 열기]
DispatchQueue.main.async {
// [카메라 열기]
if #available(iOS 13.0, *) {
guard let A_CameraVC = self.storyboard?.instantiateViewController(identifier:"A_CameraVC") as? A_Camera
else {
return
}
A_CameraVC.modalPresentationStyle = .fullScreen // 전체화면 (기본은 팝업형태)
self.present(A_CameraVC, animated: false, completion: nil) // 인텐트 이동 실시
}
// -----------------------------------------
else {
guard let A_CameraVC = self.storyboard?.instantiateViewController(withIdentifier:"A_CameraVC") as? A_Camera
else {
return
}
A_CameraVC.modalPresentationStyle = .fullScreen // 전체화면 (기본은 팝업형태)
self.present(A_CameraVC, animated: false, completion: nil) // 인텐트 이동 실시
}
}
}
}
else if (status == .denied) {
print("")
print("====================================")
print("[\(self.ACTIVITY_NAME) >> testMain() :: 카메라 사용 권한 [거부] [1]]")
print("====================================")
print("")
}
else if (status == .notDetermined) {
print("")
print("====================================")
print("[\(self.ACTIVITY_NAME) >> testMain() :: 카메라 사용 권한 [대기]]")
print("====================================")
print("")
// [권한 요청 실시]
AVCaptureDevice.requestAccess(for: .video) { (isSuccess) in
if (isSuccess) {
print("")
print("====================================")
print("[\(self.ACTIVITY_NAME) >> testMain() :: 카메라 사용 권한 [허용] [2]]")
print("====================================")
print("")
DispatchQueue.main.async {
// [카메라 열기]
if #available(iOS 13.0, *) {
guard let A_CameraVC = self.storyboard?.instantiateViewController(identifier:"A_CameraVC") as? A_Camera
else {
return
}
A_CameraVC.modalPresentationStyle = .fullScreen // 전체화면 (기본은 팝업형태)
self.present(A_CameraVC, animated: false, completion: nil) // 인텐트 이동 실시
}
// -----------------------------------------
else {
guard let A_CameraVC = self.storyboard?.instantiateViewController(withIdentifier:"A_CameraVC") as? A_Camera
else {
return
}
A_CameraVC.modalPresentationStyle = .fullScreen // 전체화면 (기본은 팝업형태)
self.present(A_CameraVC, animated: false, completion: nil) // 인텐트 이동 실시
}
}
}
else {
print("")
print("====================================")
print("[\(self.ACTIVITY_NAME) >> testMain() :: 카메라 사용 권한 [거부] [2]]")
print("====================================")
print("")
}
}
}
else {
print("")
print("====================================")
print("[\(self.ACTIVITY_NAME) >> testMain() :: 카메라 사용 권한 [ELSE]]")
print("====================================")
print("")
}
}
}
[카메라 : 소스 코드]
import UIKit
import Foundation
import AVKit
import AVFoundation
class A_Camera: UIViewController, AVCaptureMetadataOutputObjectsDelegate {
// MARK: - [전역 변수 선언 실시]
let ACTIVITY_NAME = "A_Camera"
// MARK: - [뷰 로드 실시]
override func viewDidLoad() {
super.viewDidLoad()
print("")
print("====================================")
print("[\(self.ACTIVITY_NAME) >> viewDidLoad() :: 뷰 로드 실시]")
print("====================================")
print("")
// [배경 색상 지정]
self.view.backgroundColor = .black
// [카메라 열기 실시]
self.openCamera()
}
// MARK: - [뷰 로드 완료]
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
print("")
print("====================================")
print("[\(self.ACTIVITY_NAME) >> viewWillAppear() :: 뷰 로드 완료]")
print("====================================")
print("")
}
// MARK: - [뷰 화면 표시]
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
print("")
print("====================================")
print("[\(self.ACTIVITY_NAME) >> viewDidAppear() :: 뷰 화면 표시]")
print("====================================")
print("")
}
// MARK: - [뷰 정지 상태]
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
print("")
print("====================================")
print("[\(self.ACTIVITY_NAME) >> viewWillDisappear() :: 뷰 정지 상태]")
print("====================================")
print("")
}
// MARK: - [뷰 종료 상태]
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
print("")
print("====================================")
print("[\(self.ACTIVITY_NAME) >> viewDidDisappear() :: 뷰 종료 상태]")
print("====================================")
print("")
}
// MARK: - [QR 및 바코드 스캔 실시]
var captureSession: AVCaptureSession?
var videoPreviewLayer: AVCaptureVideoPreviewLayer?
func openCamera(){
print("")
print("====================================")
print("[\(self.ACTIVITY_NAME) >> openCamera() :: 카메라 열기 수행]")
print("====================================")
print("")
let captureDevice = AVCaptureDevice.default(for: AVMediaType.video)
if let captureDevice = captureDevice {
do {
self.captureSession = AVCaptureSession()
let input: AVCaptureDeviceInput
input = try AVCaptureDeviceInput(device: captureDevice)
self.captureSession?.addInput(input)
let metadataOutput = AVCaptureMetadataOutput()
self.captureSession?.addOutput(metadataOutput)
metadataOutput.setMetadataObjectsDelegate(self, queue: DispatchQueue.main)
metadataOutput.metadataObjectTypes = [.qr, .code128] // MARK: [스캔 형식 지정]
self.videoPreviewLayer = AVCaptureVideoPreviewLayer(session: self.captureSession!)
self.videoPreviewLayer?.videoGravity = .resizeAspectFill
let uiView = UIView()
uiView.frame = CGRect(x: 0, y: 0, width: self.view.bounds.width, height: self.view.bounds.height)
self.videoPreviewLayer?.frame = CGRect(x: 0, y: 0, width: uiView.bounds.width, height: uiView.bounds.height)
uiView.layer.addSublayer(self.videoPreviewLayer!)
self.view.addSubview(uiView)
DispatchQueue.global().async {
self.captureSession?.startRunning()
}
} catch {
print("")
print("====================================")
print("[\(self.ACTIVITY_NAME) >> openCamera() :: catch 에러 발생]")
print("====================================")
print("")
}
}
}
// MARK: - [스캔 결과 확인]
func metadataOutput(_ output: AVCaptureMetadataOutput, didOutput metadataObjects: [AVMetadataObject], from connection: AVCaptureConnection) {
// [스캔 종료]
DispatchQueue.global().async {
self.captureSession!.stopRunning()
}
// [스캔 결과 없음]
if metadataObjects.count == 0 {
return
}
// [스캔 데이터 확인]
let metaDataObject = metadataObjects[0] as! AVMetadataMachineReadableCodeObject
guard let StringCodeValue = metaDataObject.stringValue else {
return
}
guard let _ = self.videoPreviewLayer?.transformedMetadataObject(for: metaDataObject) else {
return
}
// [부모 뷰에서 카메라 레이아웃 제거]
self.videoPreviewLayer?.removeFromSuperlayer()
self.view.removeFromSuperview()
// [스캔 결과 출력]
print("")
print("====================================")
print("[\(self.ACTIVITY_NAME) >> metadataOutput() :: 카메라 스캔 결과 확인]")
print("StringCodeValue :: \(StringCodeValue)")
print("====================================")
print("")
// MARK: [화면 닫기 실시]
self.dismiss(animated: false)
}
} // [클래스 종료]
[결과 출력]
반응형
'IOS' 카테고리의 다른 글
Comments