//
// SYTCodeScanerViewController.m
// SYTCodeScan
//
// Created by iMac on 15/5/6.
// Copyright (c) 2015年 S.A. All rights reserved.
//
#import "SYTCodeScanerViewController.h"
#import <AVFoundation/AVFoundation.h>
#import <AudioToolbox/AudioToolbox.h>
#import <ZXingObjC/ZXingObjC.h>
@interfaceSYTCodeScanerViewController ()<AVCaptureMetadataOutputObjectsDelegate, UIImagePickerControllerDelegate,
UINavigationControllerDelegate, UIAlertViewDelegate>
@property (nonatomic ,strong) AVCaptureSession *captureSession; //捕捉会话
@property (nonatomic, strong) AVCaptureVideoPreviewLayer *videoPreviewLayer; //预览图层layer
@property (strong, nonatomic) UIView *boxView; //扫描识别框
@property (weak, nonatomic) IBOutletUIButton *scanImageButton;
@property (nonatomic, strong) UIImagePickerController *imagePickerController;
@property (weak, nonatomic) IBOutletUIButton *openTorchButton;
@end
@implementation SYTCodeScanerViewController
- (void)viewDidLoad {
[superviewDidLoad];
[selfstartScan];
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
}
-(void)viewDidDisappear:(BOOL)animated{
[super viewDidDisappear:animated];
}
- (void)dealloc
{
[selfstopScanner];
}
- (void)startScan
{
//初始化设备(摄像头)
NSError *error = nil;
AVCaptureDevice *captureDevice = [AVCaptureDevicedefaultDeviceWithMediaType:AVMediaTypeVideo];
//创建输入流
AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:captureDevice error:&error];
if (error)
{
NSLog(@"没有摄像头:%@", error.localizedDescription);
return;
}
//创建输出流
AVCaptureMetadataOutput *output = [[AVCaptureMetadataOutputalloc] init];
//实例化捕捉会话并添加输入,输出流
if (!_captureSession) {
_captureSession = [[AVCaptureSession alloc] init];
}
//高质量采集率
[_captureSessionsetSessionPreset:AVCaptureSessionPresetHigh];
[_captureSessionaddInput:input];
[_captureSession addOutput:output];
//设置输出的代理,在主线程里刷新
[output setMetadataObjectsDelegate:selfqueue:dispatch_get_main_queue()]; //用串行队列新线程结果在UI上显示较慢
//扫码类型
[output setMetadataObjectTypes:@[AVMetadataObjectTypeQRCode, //二维码
AVMetadataObjectTypeCode39Code, //条形码 韵达和申通
AVMetadataObjectTypeCode128Code, //CODE128条码 顺丰用的
AVMetadataObjectTypeCode39Mod43Code,
AVMetadataObjectTypeEAN13Code,
AVMetadataObjectTypeEAN8Code,
AVMetadataObjectTypeCode93Code, //条形码,星号来表示起始符及终止符,如邮政EMS单上的条码
AVMetadataObjectTypeUPCECode]];
_videoPreviewLayer = [[AVCaptureVideoPreviewLayeralloc] initWithSession:_captureSession];
[_videoPreviewLayersetVideoGravity:AVLayerVideoGravityResizeAspectFill];
//添加预览图层
_videoPreviewLayer.frame = self.view.bounds;
[self.view.layeraddSublayer:_videoPreviewLayer];
[self.viewbringSubviewToFront:self.view.subviews[0]];
//扫描框
_boxView = [[UIViewalloc] initWithFrame:CGRectMake(60, 100, 200, 200)];
_boxView.layer.borderColor = [UIColorgreenColor].CGColor;
_boxView.layer.borderWidth = 1.0f;
[self.view addSubview:_boxView];
//扫描识别范围
output.rectOfInterest = CGRectMake(100 / self.view.bounds.size.height,
60 / self.view.bounds.size.width,
200 / self.view.bounds.size.height,
200 / self.view.bounds.size.width);
//开始扫描
[_captureSessionstartRunning];
}
- (void)stopScanner
{
[self openLight:NO];
[self.captureSessionstopRunning];
self.captureSession = nil;
}
#pragma mark - 扫描结果代理方法
- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection
{
[_captureSessionstopRunning];
// [_videoPreviewLayer removeFromSuperlayer];
if (metadataObjects.count > 0) {
[self playBeep];
AVMetadataMachineReadableCodeObject *obj = metadataObjects[0];
[selfshowInfoWithMessage:obj.stringValueandTitle:@"扫描成功"];
NSLog(@"扫码扫描结果obj.stringValue == %@", obj.stringValue);
}
}
#pragma mark 照片处理
-(void)getInfoWithImage:(UIImage *)img{
UIImage *loadImage= img;
CGImageRef imageToDecode = loadImage.CGImage;
ZXLuminanceSource *source = [[ZXCGImageLuminanceSourcealloc] initWithCGImage:imageToDecode];
ZXBinaryBitmap *bitmap = [ZXBinaryBitmapbinaryBitmapWithBinarizer:[ZXHybridBinarizerbinarizerWithSource:source]];
NSError *error = nil;
ZXDecodeHints *hints = [ZXDecodeHintshints];
ZXMultiFormatReader *reader = [ZXMultiFormatReaderreader];
ZXResult *result = [reader decode:bitmap
hints:hints
error:&error];
if (result) {
NSString *contents = result.text;
[selfshowInfoWithMessage:contents andTitle:@"解析成功"];
NSLog(@"相册图片contents == %@",contents);
} else {
[selfshowInfoWithMessage:nilandTitle:@"解析失败"];
}
}
- (void)showInfoWithMessage:(NSString *)message andTitle:(NSString *)title
{
UIAlertView *alter = [[UIAlertViewalloc] initWithTitle:title message:message delegate:selfcancelButtonTitle:@"确定"otherButtonTitles:nil];
[alter show];
}
#pragma - mark UIAlertViewDelegate
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.25f * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[_captureSessionstartRunning];
});
}
#pragma - mark - UIImagePickerViewControllerDelegate
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
UIImage *image = [info objectForKey:@"UIImagePickerControllerEditedImage"];
[selfdismissViewControllerAnimated:YEScompletion:^{
[self getInfoWithImage:image];
}];
}
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker
{
[_captureSessionstartRunning];
[self.imagePickerControllerdismissViewControllerAnimated:YEScompletion:nil];
}
//PS:info.plist文件已添加 Localizations 项,并选择语言为 Chinese (simplified),使相册的选择,打开,取消等按键为中文.
- (IBAction)photoPickBtn:(UIButton *)sender {
[_captureSessionstopRunning];
if (!_imagePickerController) {
_imagePickerController = [[UIImagePickerControlleralloc] init];
_imagePickerController.delegate = self;
_imagePickerController.allowsEditing = YES;
_imagePickerController.SourceType = UIImagePickerControllerSourceTypePhotoLibrary;
}
[selfpresentViewController:self.imagePickerControlleranimated:YEScompletion:nil];
}
//扫描震动
- (void)playBeep
{
SystemSoundID soundID;
AudioServicesCreateSystemSoundID((__bridgeCFURLRef)[NSURLfileURLWithPath:[[NSBundlemainBundle] pathForResource:@"beep"ofType:@"wav"]], &soundID);
AudioServicesPlaySystemSound(soundID);
// Vibrate
AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
}
//闪光灯
- (BOOL)isLightOpened
{
AVCaptureDevice *device = [AVCaptureDevicedefaultDeviceWithMediaType: AVMediaTypeVideo];
if (![device hasTorch]) {
return NO;
}else{
if ([device torchMode] == AVCaptureTorchModeOn) {
return YES;
} else {
return NO;
}
}
}
- (void)openLight:(BOOL)open
{
AVCaptureDevice *device = [AVCaptureDevicedefaultDeviceWithMediaType: AVMediaTypeVideo];//[self.reader.readerView device];
if (![device hasTorch]) {
} else {
if (open) {
// 开启闪光灯
if(device.torchMode != AVCaptureTorchModeOn ||
device.flashMode != AVCaptureFlashModeOn){
[device lockForConfiguration:nil];
[device setTorchMode:AVCaptureTorchModeOn];
[device setFlashMode:AVCaptureFlashModeOn];
[device unlockForConfiguration];
}
} else {
// 关闭闪光灯
if(device.torchMode != AVCaptureTorchModeOff ||
device.flashMode != AVCaptureFlashModeOff){
[device lockForConfiguration:nil];
[device setTorchMode:AVCaptureTorchModeOff];
[device setFlashMode:AVCaptureFlashModeOff];
[device unlockForConfiguration];
}
}
}
}
- (IBAction)openTorchButtonTouched:(id)sender {
UIButton *torchBtn = sender;
BOOL isLightOpened = [self isLightOpened];
if (isLightOpened) {
// [torchBtn setImage:[UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"scan_flash_closed" ofType:@"png"]] forState:UIControlStateNormal];
[torchBtn setBackgroundColor:[UIColorclearColor]];
[torchBtn setTitleColor:[UIColorwhiteColor] forState:UIControlStateNormal];
[self.openTorchButtonsetTitle:@"开灯"forState:UIControlStateNormal];
}
else
{
// [torchBtn setImage:[UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"scan_flash_opened" ofType:@"png"]] forState:UIControlStateNormal];
[torchBtn setBackgroundColor:[UIColorwhiteColor]];
[torchBtn setTitleColor:[UIColorblackColor] forState:UIControlStateNormal];
[self.openTorchButtonsetTitle:@"关灯"forState:UIControlStateNormal];
}
[self openLight:!isLightOpened];
}
@end