|
//
// QRCodeScanView.swift
// PaiAi
//
// Created by mac on 16/7/21.
// Copyright © 2016年 FFIB. All rights reserved.
//
import UIKit
import AVFoundation
import CoreImage
@IBDesignable public class QRCodeScanView: UIView {
var qrmaskView: QRCodeMaskView?
var qrscanner: QRCodeScanner?
var indicatorView: UIActivityIndicatorView = {
let indicator = UIActivityIndicatorView(style: .white)
indicator.frame = CGRect(x: (UIScreen.main.bounds.width - 100) / 2 ,
y: (UIScreen.main.bounds.height - 100) / 2,
width: 100,
height: 100)
return indicator
}()
public var configuration = QRCodeConfiguration() {
didSet {
qrmaskView?.configuration = configuration
}
}
public weak var delegate: QRCodeScanViewDelegate?
let picker = UIImagePickerController()
override public func layoutSubviews() {
super.layoutSubviews()
commonInit()
}
fileprivate func commonInit() {
addSubview(indicatorView)
indicatorView.startAnimating()
setQRScanner()
setMaskView()
start()
NotificationCenter.default.addObserver(self,
selector: #selector(start),
name: Notification.QRNotification.RestartNotification,
object: nil)
}
fileprivate func setMaskView() {
backgroundColor = UIColor.black
qrmaskView = QRCodeMaskView(frame: CGRect(x: 0,
y: 0,
width: bounds.width,
height: bounds.height))
guard let view = qrmaskView else { return }
view.configuration = configuration
view.backgroundColor = UIColor(r: 0, g: 0, b: 0, a: 0.2)
addSubview(view)
}
fileprivate func setQRScanner() {
qrscanner = QRCodeScanner(scanRect: bounds)
guard let qrscanner = qrscanner else { return }
qrscanner.didDecodeCode = {[weak self] res in
if let weakself = self {
weakself.delegate?.scanView(weakself,
receivedScanResult: res)
weakself.qrmaskView?.stopAnimation()
weakself.indicatorView.stopAnimating()
}
}
qrscanner.didDecodeFail = {[weak self] error in
if let weakself = self {
weakself.delegate?.scanView(weakself,
didFinshWithError: error)
weakself.indicatorView.stopAnimating()
}
}
guard let previewLayer = qrscanner.previewLayer else { return }
previewLayer.frame = bounds
layer.insertSublayer(previewLayer, at: 0)
}
@objc func start() {
let queue = DispatchQueue(label: "ffib.startScan.com")
queue.async {
self.qrscanner?.startScan()
DispatchQueue.main.async {
self.qrmaskView?.startAnimation()
self.indicatorView.stopAnimating()
}
}
}
public func openLight() {
guard let device = AVCaptureDevice.default(for: AVMediaType.video) else { return }
do {
try device.lockForConfiguration()
if device.hasTorch && device.isTorchAvailable {
if device.isTorchActive {
device.torchMode = .off
} else {
device.torchMode = .on
}
}
} catch {
print("open light error")
}
}
public func openPhotoLibrary(ctl: UIViewController) {
indicatorView.startAnimating()
let status = AVCaptureDevice.authorizationStatus(for: AVMediaType.video)
if status == .notDetermined || status == .authorized {
picker.sourceType = .photoLibrary
picker.delegate = self
ctl.present(picker, animated: true, completion: nil)
} else {
let alert = UIAlertController(title: "拒绝访问", message: "请在设置-隐私-相机中允许访问相册", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "确定", style: .default, handler: nil))
ctl.present(alert, animated: true, completion: nil)
}
}
}
extension QRCodeScanView: UIImagePickerControllerDelegate, UINavigationControllerDelegate {
public func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
picker.dismiss(animated: true) {
guard let image = info[UIImagePickerController.InfoKey.originalImage] as? UIImage else { return }
if let res = image.decodeQRCodeInImage() {
self.qrscanner?.stopScan()
self.qrmaskView?.stopAnimation()
self.delegate?.scanView(self,
receivedScanResult: QRCodeScanResult(metadataType: AVMetadataObject.ObjectType.qr.rawValue,
result: res))
} else {
let error = NSError(domain: "decode qr code error",
code: 101,
userInfo: nil)
self.delegate?.scanView(self,
didFinshWithError: error)
}
self.indicatorView.stopAnimating()
}
}
public func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
picker.dismiss(animated: true, completion: nil)
}
}
//qr code identify the pictures
extension UIImage {
/// 识别图片内的二维码
///
/// - Returns: 二维码信息
public func decodeQRCodeInImage() -> String? {
guard let detector = CIDetector(ofType: CIDetectorTypeQRCode, context: nil, options: nil),
let cgImage1 = self.cgImage else { return nil }
let result = detector.features(in: CIImage(cgImage: cgImage1), options: [CIDetectorAccuracy: CIDetectorAccuracyHigh])
guard let first = (result as? [CIQRCodeFeature])?.first else { return nil }
return first.messageString
}
}
|