採用系統API實現的二維碼掃描、識別和生成

直接上代碼吧,注意這些代碼需要iOS7以上,尤其那個從圖片中識別二維碼需要iOS8;

1、通過攝像頭識別

//
//  QRViewController.h
//  CommonProject
//
//  Created by wuyoujian on 16/5/13.
//  Copyright © 2016年 wuyoujian. All rights reserved.
//

#import <UIKit/UIKit.h>

typedef NS_ENUM(NSInteger, QRCodeScanStatus) {
    QRCodeScanStatusSuccess,
    QRCodeScanStatusFail,
    QRCodeScanStatusCancel,
};

typedef void(^QRCodeFinishBlock)(NSString *result,QRCodeScanStatus status);

@interface QRViewController :UIViewController

@property (nonatomic,copy)QRCodeFinishBlock finishBlock;

- (void)startScanQRCode;
- (void)startScanQRCodeWithFinish:(QRCodeFinishBlock)finishBlock;

@end

//
//  QRViewController.m
//  CommonProject
//
//  Created by wuyoujian on 16/5/13.
//  Copyright © 2016年 wuyoujian. All rights reserved.
//

#import "QRViewController.h"
#import <AVFoundation/AVFoundation.h>
#import "DispatchTimer.h"

@interface QRViewController ()<AVCaptureMetadataOutputObjectsDelegate>
@property (nonatomic,strong)AVCaptureSession              *session;
@property (nonatomic,strong)AVCaptureVideoPreviewLayer    *preview;
@property (nonatomic,strong)UIImageView                   *lineImageView;

@property (nonatomic,strong)DispatchTimer                 *timer;

@end

@implementation QRViewController


- (BOOL)prefersStatusBarHidden {
    returnYES;
}

-(void)dealloc {
    [_timerinvalidate];
}

- (void)viewDidLoad {

    [superviewDidLoad];
    [self.viewsetBackgroundColor:[UIColorblackColor]];

    [selflayoutCaptureView];
}

- (void)initCaptureDevice {
    CGRect previewFrame =CGRectMake(0,0,self.view.width,self.view.height);

    AVCaptureDevice *device = [AVCaptureDevicedefaultDeviceWithMediaType:AVMediaTypeVideo];

    NSError *error =nil;
    AVCaptureDeviceInput *input = [AVCaptureDeviceInputdeviceInputWithDevice:deviceerror:&error];

    if (_finishBlock) {
        _finishBlock(nil,QRCodeScanStatusFail);
    }

    AVCaptureMetadataOutput *output = [[AVCaptureMetadataOutputalloc]init];
    [output setMetadataObjectsDelegate:selfqueue:dispatch_get_main_queue()];

    self.session = [[AVCaptureSessionalloc]init];

    if ([self.sessioncanAddInput:input]) {
        [self.sessionaddInput:input];
    }

    if ([self.sessioncanAddOutput:output]) {
        [self.sessionaddOutput:output];
    }

    output.metadataObjectTypes =@[AVMetadataObjectTypeQRCode,AVMetadataObjectTypeCode128Code,AVMetadataObjectTypeEAN8Code,AVMetadataObjectTypeUPCECode,AVMetadataObjectTypeCode39Code,AVMetadataObjectTypePDF417Code,AVMetadataObjectTypeAztecCode,AVMetadataObjectTypeCode93Code,AVMetadataObjectTypeEAN13Code,AVMetadataObjectTypeCode39Mod43Code];



    self.preview = [AVCaptureVideoPreviewLayerlayerWithSession:self.session];
    self.preview.videoGravity =AVLayerVideoGravityResize;
    self.preview.frame = previewFrame;

    [self.view.layeraddSublayer:self.preview];

    if ([UIScreenmainScreen].bounds.size.height ==480) {
        [self.sessionsetSessionPreset:AVCaptureSessionPreset640x480];
    } else {
        [self.sessionsetSessionPreset:AVCaptureSessionPresetHigh];
    }

    [output rectOfInterest];

    UIButton *cancelBtn = [UIButtonbuttonWithType:UIButtonTypeSystem];
    [cancelBtn setFrame:CGRectMake(10,20,40,30)];
    [cancelBtn.titleLabelsetFont:[UIFontsystemFontOfSize:16]];
    [cancelBtn setTitle:@"取消"forState:UIControlStateNormal];
    [cancelBtn addTarget:selfaction:@selector(cancelBtnClick:)forControlEvents:UIControlEventTouchUpInside];
    [self.viewaddSubview:cancelBtn];
}

- (void)startScanQRCode {
    [self.sessionstartRunning];
}

- (void)startScanQRCodeWithFinish:(QRCodeFinishBlock)finishBlock {
    self.finishBlock = finishBlock;

    [selfstartScanQRCode];
}

- (void)layoutCaptureView {

    [selfinitCaptureDevice];

    UIImageView *imageView = [[UIImageViewalloc]initWithImage:[UIImageimageNamed:@"pick_bg.png"]];
    imageView.frame =CGRectMake(self.view.bounds.size.width * 0.5 - 140,self.view.bounds.size.height * 0.5 - 140,280,280);
    [self.viewaddSubview:imageView];


    self.lineImageView = [[UIImageViewalloc]initWithFrame:CGRectMake(30,10,220,2)];
    _lineImageView.image = [UIImageimageNamed:@"line.png"];
    [imageView addSubview:_lineImageView];


    __weakQRViewController *wself =self;
    [[DispatchTimersharedDispatchTimer]createDispatchTimerInterval:3.0block:^{
        QRViewController *sself = wself;

        [sself scanAnimation];
    } repeats:YES];
}



- (void)scanAnimation {
    [UIViewanimateWithDuration:2.8delay:0options:UIViewAnimationOptionCurveLinearanimations:^{
        _lineImageView.frame =CGRectMake(30,260,220,2);

    } completion:^(BOOL finished) {
        _lineImageView.frame =CGRectMake(30,10,220,2);
    }];
}

- (void)cancelBtnClick:(id)sender {
    if (_finishBlock) {
        _finishBlock(nil,QRCodeScanStatusCancel);
    }
}

#pragma mark - AVCaptureMetadataOutputObjectsDelegate
- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection {

    [self.sessionstopRunning];
    [self.previewremoveFromSuperlayer];

    NSString *val =nil;
    if (metadataObjects.count >0) {
        AVMetadataMachineReadableCodeObject *obj = metadataObjects[0];
        val = obj.stringValue;

        if (_finishBlock) {
            _finishBlock(val,QRCodeScanStatusSuccess);
        }
    }
}


@end

上面用的類:DispatchTimer 請參考我的這個博客:http://blog.csdn.net/wuyoujian0313/article/details/51799782

2、生成二維碼和條形碼

// 生成二維碼圖片
+ (UIImage *)generateQRCode:(NSString *)code width:(CGFloat)width height:(CGFloat)height {
    CIFilter *filter = [CIFilterfilterWithName:@"CIQRCodeGenerator"];
    [filter setDefaults];

    NSData *data = [codedataUsingEncoding:NSUTF8StringEncoding];
    [filter setValue:dataforKey:@"inputMessage"];
    [filter setValue:@"H"forKey:@"inputCorrectionLevel"];
    CIImage *outputImage = [filteroutputImage];

    CIContext *context = [CIContextcontextWithOptions:nil];
    CGImageRef cgImage = [contextcreateCGImage:outputImage
                                       fromRect:[outputImageextent]];

    UIImage *image = [UIImageimageWithCGImage:cgImage
                                         scale:1.
                                   orientation:UIImageOrientationUp];

    UIImage *resized =nil;
    UIGraphicsBeginImageContext(CGSizeMake(width, height));
    CGContextRef contextCurrent =UIGraphicsGetCurrentContext();
    CGContextSetInterpolationQuality(contextCurrent,kCGInterpolationNone);
    [image drawInRect:CGRectMake(0,0, width, height)];
    resized = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    CGImageRelease(cgImage);

    return resized;
}

// 生成條形碼
+ (UIImage *)generateBarCode:(NSString *)code width:(CGFloat)width height:(CGFloat)height {
    CIFilter *filter = [CIFilterfilterWithName:@"CICode128BarcodeGenerator"];
    [filter setDefaults];

    NSData *data = [codedataUsingEncoding:NSUTF8StringEncoding];
    [filter setValue:dataforKey:@"inputMessage"];
    [filter setValue:@(5.00)forKey:@"inputQuietSpace"];
    CIImage *outputImage = [filteroutputImage];

    CIContext *context = [CIContextcontextWithOptions:nil];
    CGImageRef cgImage = [contextcreateCGImage:outputImage
                                       fromRect:[outputImageextent]];

    UIImage *image = [UIImageimageWithCGImage:cgImage
                                         scale:1.
                                   orientation:UIImageOrientationUp];

    UIImage *resized =nil;
    UIGraphicsBeginImageContext(CGSizeMake(width, height));
    CGContextRef contextCurrent =UIGraphicsGetCurrentContext();
    CGContextSetInterpolationQuality(contextCurrent,kCGInterpolationNone);
    [image drawInRect:CGRectMake(0,0, width, height)];
    resized = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    CGImageRelease(cgImage);

    return resized;
}

3、從圖片中識別二維碼:

- (NSArray *)recognitionQRCodeFromImage {

    // 把圖片縮放到硬件的分辨率
    CGSize scaleSize = [DeviceInfogetDeviceScreenSize];
    UIImage *imageScale = [selfresizedImageByMagick:[NSStringstringWithFormat:@"%ldx%ld",(long)scaleSize.width,(long)scaleSize.height]];
    CIImage *ciImage = [[CIImagealloc]initWithImage:imageScale];

    //CIImage *ciImage = [[CIImage alloc] initWithImage:self];
    //創建探測器
    if ([DeviceInfoisOS8]) {
        CIDetector *detector = [CIDetectordetectorOfType:CIDetectorTypeQRCode
                                                  context:[CIContextcontextWithOptions:nil]
                                                  options:@{CIDetectorAccuracy:CIDetectorAccuracyLow,CIDetectorMinFeatureSize:@1.0}];
        NSArray<CIFeature*> *features = [detectorfeaturesInImage:ciImage];

        //取出探測到的數據
        NSMutableArray *results = [[NSMutableArrayalloc]init];
        for (CIQRCodeFeature *resultin features) {
            if ([result.typeisEqualToString:CIFeatureTypeQRCode]) {
                [results addObject:result.messageString];
            }
        }

        return results;
    }

    returnnil;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章