iOS 七以上原生二维码、条码扫描(ZXingObjC相册读取)

iOS 7以上原生二维码、条码扫描(ZXingObjC相册读取)

//

//  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