1,條碼(一維碼)的掃描讀取
原來寫過一篇文章,介紹如何使用網路攝影機掃描讀取二維碼:Swift - 二維碼QRCode的讀取(從圖片讀取 ,或通過網路攝影機掃描)要通過網路攝影機讀取條碼,只需要將原來二維碼讀取代碼中 metadataObjectTypes 做如下修改即可:
self.output.metadataObjectTypes = [AVMetadataObjectTypeEAN13Code,
AVMetadataObjectTypeEAN8Code, AVMetadataObjectTypeCode128Code,
AVMetadataObjectTypeCode39Code,AVMetadataObjectTypeCode93Code]
2,拉近鏡頭,改善條碼讀取效果
有網友反應,如果條碼太小的時候(比如iwatch上支付寶的產生的小條碼)就會識別不出來。
解決辦法是:像支付寶、QQ一樣,通過代碼拉近鏡頭焦距,放大內容地區讓機器更好的識別。
下面左圖是原始大小,右圖將畫面放大了1.5倍:
import UIKit
import AVFoundation
class ViewController: UIViewController, AVCaptureMetadataOutputObjectsDelegate,
UIAlertViewDelegate{
var scanRectView:UIView!
var device:AVCaptureDevice!
var input:AVCaptureDeviceInput!
var output:AVCaptureMetadataOutput!
var session:AVCaptureSession!
var preview:AVCaptureVideoPreviewLayer!
override func viewDidLoad() {
super.viewDidLoad()
fromCamera()
}
//通過網路攝影機掃描
func fromCamera() {
do{
self.device = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeVideo)
self.input = try AVCaptureDeviceInput(device: device)
self.output = AVCaptureMetadataOutput()
output.setMetadataObjectsDelegate(self, queue: dispatch_get_main_queue())
self.session = AVCaptureSession()
if UIScreen.mainScreen().bounds.size.height<500 {
self.session.sessionPreset = AVCaptureSessionPreset640x480
}else{
self.session.sessionPreset = AVCaptureSessionPresetHigh
}
self.session.addInput(self.input)
self.session.addOutput(self.output)
self.output.metadataObjectTypes = [AVMetadataObjectTypeEAN13Code,
AVMetadataObjectTypeEAN8Code, AVMetadataObjectTypeCode128Code,
AVMetadataObjectTypeCode39Code,AVMetadataObjectTypeCode93Code]
//計算中間可探測地區
let windowSize:CGSize = UIScreen.mainScreen().bounds.size;
let scanSize:CGSize = CGSizeMake(windowSize.width*3/4,
windowSize.width*3/4);
var scanRect:CGRect = CGRectMake((windowSize.width-scanSize.width)/2,
(windowSize.height-scanSize.height)/2, scanSize.width, scanSize.height);
//計算rectOfInterest 注意x,y交換位置
scanRect = CGRectMake(scanRect.origin.y/windowSize.height,
scanRect.origin.x/windowSize.width,
scanRect.size.height/windowSize.height,
scanRect.size.width/windowSize.width);
//設定可探測地區
self.output.rectOfInterest = scanRect
self.preview = AVCaptureVideoPreviewLayer(session:self.session)
self.preview.videoGravity = AVLayerVideoGravityResizeAspectFill
self.preview.frame = UIScreen.mainScreen().bounds
self.view.layer.insertSublayer(self.preview, atIndex:0)
//添加中間的探測地區綠框
self.scanRectView = UIView();
self.view.addSubview(self.scanRectView)
self.scanRectView.frame = CGRectMake(0, 0, scanSize.width, scanSize.height);
self.scanRectView.center = CGPointMake(
CGRectGetMidX(UIScreen.mainScreen().bounds),
CGRectGetMidY(UIScreen.mainScreen().bounds));
self.scanRectView.layer.borderColor = UIColor.greenColor().CGColor
self.scanRectView.layer.borderWidth = 1;
//開始捕獲
self.session.startRunning()
//放大
do {
try self.device!.lockForConfiguration()
} catch _ {
NSLog("Error: lockForConfiguration.");
}
self.device!.videoZoomFactor = 1.5
self.device!.unlockForConfiguration()
}catch _ as NSError{
//列印錯誤訊息
let errorAlert = UIAlertView(title: "提醒",
message: "請在iPhone的\"設定-隱私-相機\"選項中,允許本程式訪問您的相機",
delegate: self,
cancelButtonTitle: "確定")
errorAlert.show()
}
}
//網路攝影機捕獲
func captureOutput(captureOutput: AVCaptureOutput!,
didOutputMetadataObjects metadataObjects: [AnyObject]!,
fromConnection connection: AVCaptureConnection!) {
var stringValue:String?
if metadataObjects.count > 0 {
let metadataObject = metadataObjects[0]
as! AVMetadataMachineReadableCodeObject
stringValue = metadataObject.stringValue
if stringValue != nil{
self.session.stopRunning()
}
}
self.session.stopRunning()
//輸出結果
let alertView = UIAlertView(title: "二維碼", message: stringValue,
delegate: self, cancelButtonTitle: "確定")
alertView.show()
}
//訊息框確認後消失
func alertView(alertView: UIAlertView, willDismissWithButtonIndex buttonIndex: Int) {
//繼續掃描
self.session.startRunning()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}