iOS 二維碼 2
//
// SYQRCodeViewController.m
// SYQRCodeDemo
//
// Created by sunbb on 15-1-9.
// Copyright (c) 2015年 SY. All rights reserved.
//
#import "SYQRCodeViewController.h"
#import <AVFoundation/AVFoundation.h>
//裝置寬/高/座標
#define kDeviceWidth [UIScreen mainScreen].bounds.size.width
#define KDeviceHeight [UIScreen mainScreen].bounds.size.height
#define KDeviceFrame [UIScreen mainScreen].bounds
staticconstfloat kLineMinY = 185;
staticconstfloat kLineMaxY = 385;
staticconstfloat kReaderViewWidth = 200;
staticconstfloat kReaderViewHeight = 200;
@interface SYQRCodeViewController () <AVCaptureMetadataOutputObjectsDelegate>
@property
@property (nonatomic, strong) AVCaptureVideoPreviewLayer *qrVideoPreviewLayer;//讀取
@property (nonatomic, strong) UIImageView *line;//互動線
@property (nonatomic, strong) NSTimer *lineTimer;//互動線控制
@end
@implementation SYQRCodeViewController
- (void
{
[superviewDidLoad];
// Do any additional setup after loading the view.
self.view.backgroundColor = [UIColorwhiteColor];
[selfinitUI];
[selfsetOverlayPickerView];
[selfstartSYQRCodeReading];
[selfinitTitleView];
[selfcreateBackBtn];
}
- (void)dealloc
{
if (_qrSession) {
[_qrSessionstopRunning];
_qrSession = nil;
}
if (_qrVideoPreviewLayer) {
_qrVideoPreviewLayer = nil;
}
if (_line) {
_line = nil;
}
if (_lineTimer)
{
[_lineTimerinvalidate];
_lineTimer = nil;
}
}
- (void)initTitleView
{
UIView *bgView = [[UIViewalloc] initWithFrame:CGRectMake(0,0,kDeviceWidth, 64)];
bgView.backgroundColor = [UIColorcolorWithRed:62.0/255green:199.0/255blue:153.0/255alpha:1.0];
[self.viewaddSubview:bgView];
UILabel *titleLab = [[UILabelalloc] initWithFrame:CGRectMake((kDeviceWidth - 40) / 2.0, 28, 40, 20)];
//scanCropView.image=[UIImage imageNamed:@""];
//titleLab.layer.borderColor = [UIColor greenColor].CGColor;
//titleLab.layer.borderWidth = 2.0;
//titleLab.backgroundColor = [UIColor colorWithRed:62.0/255 green:199.0/255 blue:153.0/255 alpha:1.0];
titleLab.text = @"掃題";
titleLab.shadowColor = [UIColorlightGrayColor];
titleLab.shadowOffset = CGSizeMake(0, - 1);
titleLab.font = [UIFontboldSystemFontOfSize:18.0];
titleLab.textColor = [UIColorwhiteColor];
titleLab.textAlignment = NSTextAlignmentCenter;
[self.viewaddSubview:titleLab];
}
- (void)createBackBtn
{
UIButton *btn = [UIButtonbuttonWithType:UIButtonTypeCustom];
[btn setFrame:CGRectMake(20, 28, 60, 24)];
[btn setImage:[UIImageimageNamed:@"bar_back"] forState:UIControlStateNormal];
[btn addTarget:selfaction:@selector(cancleSYQRCodeReading) forControlEvents:UIControlEventTouchUpInside];
[self.viewaddSubview:btn];
}
- (void)initUI
{
AVCaptureDevice *device = [AVCaptureDevicedefaultDeviceWithMediaType:AVMediaTypeVideo];
//攝像頭判斷
NSError *error = nil;
AVCaptureDeviceInput *input = [AVCaptureDeviceInputdeviceInputWithDevice:device error:&error];
if (error)
{
NSLog(@"沒有攝像頭-%@", error.localizedDescription);
return;
}
//設定輸出(Metadata元資料)
AVCaptureMetadataOutput *output = [[AVCaptureMetadataOutputalloc] init];
//設定輸出的代理
//使用主執行緒佇列,相應比較同步,使用其他佇列,相應不同步,容易讓使用者產生不好的體驗
[output setMetadataObjectsDelegate:selfqueue:dispatch_get_main_queue()];
[output setRectOfInterest:[selfgetReaderViewBoundsWithSize:CGSizeMake(kReaderViewWidth, kReaderViewHeight)]];
//拍攝會話
AVCaptureSession *session = [[AVCaptureSessionalloc] init];
// 讀取質量,質量越高,可讀取小尺寸的二維碼
if ([session canSetSessionPreset:AVCaptureSessionPreset1920x1080])
{
[session setSessionPreset:AVCaptureSessionPreset1920x1080];
}
elseif ([session canSetSessionPreset:AVCaptureSessionPreset1280x720])
{
[session setSessionPreset:AVCaptureSessionPreset1280x720];
}
else
{
[session setSessionPreset:AVCaptureSessionPresetPhoto];
}
if ([session canAddInput:input])
{
[session addInput:input];
}
if ([session canAddOutput:output])
{
[session addOutput:output];
}
//設定輸出的格式
//一定要先設定會話的輸出為output之後,再指定輸出的元資料型別
[output setMetadataObjectTypes:@[AVMetadataObjectTypeQRCode]];
//設定預覽圖層
AVCaptureVideoPreviewLayer *preview = [AVCaptureVideoPreviewLayerlayerWithSession:session];
//設定preview圖層的屬性
//preview.borderColor = [UIColor redColor].CGColor;
//preview.borderWidth = 1.5;
[preview setVideoGravity:AVLayerVideoGravityResizeAspectFill];
//設定preview圖層的大小
preview.frame = self.view.layer.bounds;
//[preview setFrame:CGRectMake(0, 0, kDeviceWidth, KDeviceHeight)];
//將圖層新增到檢視的圖層
[self.view.layerinsertSublayer:preview atIndex:0];
//[self.view.layer addSublayer:preview];
self.qrVideoPreviewLayer = preview;
self.qrSession = session;
}
- (CGRect)getReaderViewBoundsWithSize:(CGSize)asize
{
returnCGRectMake(kLineMinY / KDeviceHeight, ((kDeviceWidth - asize.width) / 2.0) / kDeviceWidth, asize.height / KDeviceHeight, asize.width / kDeviceWidth);
}
- (void)setOverlayPickerView
{
//畫中間的基準線
_line = [[UIImageViewalloc] initWithFrame:CGRectMake((kDeviceWidth - 300) / 2.0, kLineMinY, 300, 12 * 300 / 320.0)];
[_linesetImage:[UIImageimageNamed:@"QRCodeLine"]];
[self.viewaddSubview:_line];
//最上部view
UIView* upView = [[UIViewalloc] initWithFrame:CGRectMake(0, 0, kDeviceWidth, kLineMinY)];//80
upView.alpha = 0.3;
upView.backgroundColor = [UIColorblackColor];
[self.viewaddSubview:upView];
//左側的view
UIView *leftView = [[UIViewalloc] initWithFrame:CGRectMake(0, kLineMinY, (kDeviceWidth - kReaderViewWidth) / 2.0, kReaderViewHeight)];
leftView.alpha = 0.3;
leftView.backgroundColor = [UIColorblackColor];
[self.viewaddSubview:leftView];
//右側的view
UIView *rightView = [[UIViewalloc] initWithFrame:CGRectMake(kDeviceWidth - CGRectGetMaxX(leftView.frame), kLineMinY, CGRectGetMaxX(leftView.frame), kReaderViewHeight)];
rightView.alpha = 0.3;
rightView.backgroundColor = [UIColorblackColor];
[self.viewaddSubview:rightView];
CGFloat space_h = KDeviceHeight - kLineMaxY;
//底部view
UIView *downView = [[UIViewalloc] initWithFrame:CGRectMake(0, kLineMaxY, kDeviceWidth, space_h)];
downView.alpha = 0.3;
downView.backgroundColor = [UIColorblackColor];
[self.viewaddSubview:downView];
//四個邊角
UIImage *cornerImage = [UIImageimageNamed:@"QRCodeTopLeft"];
//左側的view
UIImageView *leftView_image = [[UIImageViewalloc] initWithFrame:CGRectMake(CGRectGetMaxX(leftView.frame) - cornerImage.size.width / 2.0, CGRectGetMaxY(upView.frame) - cornerImage.size.height / 2.0, cornerImage.size.width, cornerImage.size.height)];
leftView_image.image = cornerImage;
[self.viewaddSubview:leftView_image];
cornerImage = [UIImageimageNamed:@"QRCodeTopRight"];
//右側的view
UIImageView *rightView_image = [[UIImageViewalloc] initWithFrame:CGRectMake(CGRectGetMinX(rightView.frame) - cornerImage.size.width / 2.0, CGRectGetMaxY(upView.frame) - cornerImage.size.height / 2.0, cornerImage.size.width, cornerImage.size.height)];
rightView_image.image = cornerImage;
[self.viewaddSubview:rightView_image];
cornerImage = [UIImageimageNamed:@"QRCodebottomLeft"];
//底部view
UIImageView *downView_image = [[UIImageViewalloc] initWithFrame:CGRectMake(CGRectGetMaxX(leftView.frame) - cornerImage.size.width / 2.0, CGRectGetMinY(downView.frame) - cornerImage.size.height / 2.0, cornerImage.size.width, cornerImage.size.height)];
downView_image.image = cornerImage;
//downView.backgroundColor = [UIColor blackColor];
[self.viewaddSubview:downView_image];
cornerImage = [UIImageimageNamed:@"QRCodebottomRight"];
UIImageView *downViewRight_image = [[UIImageViewalloc] initWithFrame:CGRectMake(CGRectGetMinX(rightView.frame) - cornerImage.size.width / 2.0, CGRectGetMinY(downView.frame) - cornerImage.size.height / 2.0, cornerImage.size.width, cornerImage.size.height)];
downViewRight_image.image = cornerImage;
//downView.backgroundColor = [UIColor blackColor];
[self.viewaddSubview:downViewRight_image];
//說明label
UILabel *labIntroudction = [[UILabelalloc] init];
labIntroudction.backgroundColor = [UIColorclearColor];
labIntroudction.frame = CGRectMake(CGRectGetMaxX(leftView.frame), CGRectGetMinY(downView.frame) + 25, kReaderViewWidth, 20);
labIntroudction.textAlignment = NSTextAlignmentCenter;
labIntroudction.font = [UIFontboldSystemFontOfSize:13.0];
labIntroudction.textColor = [UIColorwhiteColor];
labIntroudction.text = @"將二維碼置於框內,即可自動掃描";
[self.viewaddSubview:labIntroudction];
UIView *scanCropView = [[UIViewalloc] initWithFrame:CGRectMake(CGRectGetMaxX(leftView.frame) - 1,kLineMinY,self.view.frame.size.width - 2 * CGRectGetMaxX(leftView.frame) + 2, kReaderViewHeight + 2)];
scanCropView.layer.borderColor = [UIColorgreenColor].CGColor;
scanCropView.layer.borderWidth = 2.0;
[self.viewaddSubview:scanCropView];
}
#pragma mark -
#pragma mark 輸出代理方法
//此方法是在識別到QRCode,並且完成轉換
//如果QRCode的內容越大,轉換需要的時間就越長
- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection
{
//掃描結果
if (metadataObjects.count > 0)
{
[selfstopSYQRCodeReading];
AVMetadataMachineReadableCodeObject *obj = metadataObjects[0];
if (obj.stringValue && ![obj.stringValueisEqualToString:@""] && obj.stringValue.length > 0)
{
NSLog(@"---------%@",obj.stringValue);
if ([obj.stringValuecontainsString:@"http"])
{
if (self.SYQRCodeSuncessBlock) {
self.SYQRCodeSuncessBlock(self,obj.stringValue);
}
}
else
{
if (self.SYQRCodeFailBlock) {
self.SYQRCodeFailBlock(self);
}
}
}
else
{
if (self.SYQRCodeFailBlock) {
self.SYQRCodeFailBlock(self);
}
}
}
else
{
if (self.SYQRCodeFailBlock) {
self.SYQRCodeFailBlock(self);
}
}
}
#pragma mark -
#pragma mark 互動事件
- (void)startSYQRCodeReading
{
_lineTimer = [NSTimerscheduledTimerWithTimeInterval:1.0 / 20target:selfselector:@selector(animationLine) userInfo:nilrepeats