iOS二维码生成及扫码

 概要
        现在越来越多的应用加入二维码相关的业务,在iOS开发市场上很多开发人员都在使用第三方的扫码与生成二维码的控件,个人认为此类的第三方控件识别度不高。最近正好整理新框架的事情,研究了一下。具体代码如下
 生成二维码代码
/**
 *  @author 半    饱, 15-12-18
 *
 *  @brief  生成二维码图片
 *
 *  @param code   生成二维码图片内容
 *  @param width  二维码图片宽度
 *  @param height 二维码图片高度
 *
 *  @return 返回UIImage对象
 */
- (UIImage *)generateQRCode:(NSString *)code width:(CGFloat)width height:(CGFloat)height {
    CIImage *qrcodeImage;
    NSData *data = [code dataUsingEncoding:NSISOLatin1StringEncoding allowLossyConversion:false];
    CIFilter *filter = [CIFilter filterWithName:@"CIQRCodeGenerator"];
    
    [filter setValue:data forKey:@"inputMessage"];
    [filter setValue:@"H" forKey:@"inputCorrectionLevel"];
    qrcodeImage = [filter outputImage];
    
    CGFloat scaleX = width / qrcodeImage.extent.size.width;
    CGFloat scaleY = height / qrcodeImage.extent.size.height;
    CIImage *transformedImage = [qrcodeImage imageByApplyingTransform:CGAffineTransformScale(CGAffineTransformIdentity, scaleX, scaleY)];
    
    return [UIImage imageWithCIImage:transformedImage];
}

 扫描二维码代码
#import <AVFoundation/AVFoundation.h>

static const float lightWidth = 240.f;
static const float lightHeight = 240.f;
static const float crossLineWidth = 2.f;
static const float crossLineHeight = 15.f;

@interface BBScanCodeViewController ()<AVCaptureMetadataOutputObjectsDelegate> {
    float leftWith;
    float topHeight;
}
@property (strong , nonatomic ) AVCaptureDevice *captureDevice;
@property (strong , nonatomic ) AVCaptureDeviceInput *captureInput;
@property (strong , nonatomic ) AVCaptureMetadataOutput *captureOutput;
@property (strong , nonatomic ) AVCaptureSession *captureSession;
@property (strong , nonatomic ) AVCaptureVideoPreviewLayer *capturePreview;

@property (strong,nonatomic) UIButton *flashLightBtn;
@property (strong,nonatomic) UIImageView *lineImageView;

@end

@implementation BBScanCodeViewController
@synthesize captureDevice = _captureDevice;
@synthesize captureInput = _captureInput;
@synthesize captureOutput = _captureOutput;
@synthesize capturePreview = _capturePreview;
@synthesize captureSession = _captureSession;
@synthesize  delegate = _delegate;
@synthesize  isRectScan = _isRectScan;
@synthesize lineImageView = _lineImageView;
@synthesize  flashLightBtn = _flashLightBtn;
- (void)viewDidLoad {
    
    [super viewDidLoad];
    self.isShowNavigationItem = YES;
    CGRect screenRect = [UIScreen mainScreen].bounds;
    leftWith = (screenRect.size.width - lightWidth) /  2;
    topHeight =(screenRect.size.height - lightHeight) /  2;
    
#if !TARGET_IPHONE_SIMULATOR
    [self initScanCode];
#endif
    [self initLayer];
    [self initViewControl];
    
    

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(willResignActiveNotification) name:UIApplicationWillResignActiveNotification object:nil]; //监听是否触发home键挂起程序.
   [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didBecomeActiveNotification) name:UIApplicationDidBecomeActiveNotification object:nil]; //监听是否重新进入程序程序.
}

-(void)viewWillDisappear:(BOOL)animated {
     [self stopScanCode];
    [super viewWillDisappear:animated];
}

- (void)willResignActiveNotification {
    _flashLightBtn.selected = NO;
}
- (void)didBecomeActiveNotification {

}
//加载界面上的控件,如:加上闪光灯按钮等
- (void)initViewControl {

    @autoreleasepool {
        _flashLightBtn = [UIButton buttonWithType:UIButtonTypeCustom];
        [_flashLightBtn setImage:[UIImage imageNamed:@"OpenFlashLight.png"] forState:UIControlStateNormal];
        [_flashLightBtn setImage:[UIImage imageNamed:@"CloseFlashLight.png"] forState:UIControlStateSelected];
        _flashLightBtn.frame = CGRectMake(leftWith, 80.f, 30.f, 30.f);
        [_flashLightBtn addTarget:self action:@selector(systemFlashLight) forControlEvents:UIControlEventTouchUpInside];
        [self.view addSubview:_flashLightBtn];
        
        _lineImageView = [[UIImageView alloc] initWithImage:nil];
        _lineImageView.backgroundColor = [UIColor greenColor];
        _lineImageView.frame = CGRectMake(leftWith, topHeight, lightWidth, 2);
        [self.view addSubview:_lineImageView];
        [self scanLineAnimation];
    }
    
}

- (void)scanLineAnimation {
    [UIView beginAnimations:nil context:nil];
    [UIView setAnimationDuration:4.f];
    //设置代理
    [UIView setAnimationDelegate:self];
    //设置动画执行完毕调用的事件
    [UIView setAnimationDidStopSelector:@selector(didViewAnimation)];
    _lineImageView.frame = CGRectMake(leftWith,topHeight + lightHeight-2,lightWidth,2);
    [UIView commitAnimations];

}

-(void)didViewAnimation {
//    self.navigationController
    _lineImageView.frame = CGRectMake(leftWith, topHeight, lightWidth, 2);
    [self scanLineAnimation];
}

- (void)insertLayerWithFrame:(CGRect)frame withBackgroundColor:(UIColor *)backgroundColor {
    @autoreleasepool {
        CALayer *layer = [CALayer layer];
        layer.backgroundColor = backgroundColor.CGColor;
        layer.frame = frame;
        [self.view.layer addSublayer:layer];
    }
}
//初始化layer层,绘制半透明区域
-(void) initLayer {
    //公共参数
    UIColor *fillColor = [UIColor colorWithRed:0xae/255.f green:0xae/255.f blue:0xae/255.f alpha:0.4];
    UIColor *crossColor = [UIColor greenColor];
    CGRect screenRect = [UIScreen mainScreen].bounds;
    [self insertLayerWithFrame:CGRectMake(0, 0, leftWith, screenRect.size.height) withBackgroundColor:fillColor];
    [self insertLayerWithFrame:CGRectMake(leftWith, 0, lightWidth, topHeight) withBackgroundColor:fillColor];
    [self insertLayerWithFrame:CGRectMake(leftWith + lightWidth, 0, leftWith, screenRect.size.height) withBackgroundColor:fillColor];
    [self insertLayerWithFrame:CGRectMake(leftWith, topHeight + lightHeight, lightWidth, topHeight) withBackgroundColor:fillColor];
    
    
    [self insertLayerWithFrame:CGRectMake(leftWith, topHeight, crossLineWidth, crossLineHeight) withBackgroundColor:crossColor];
    [self insertLayerWithFrame:CGRectMake(leftWith, topHeight, crossLineHeight, crossLineWidth) withBackgroundColor:crossColor];
    
    [self insertLayerWithFrame:CGRectMake(leftWith + lightWidth - crossLineHeight, topHeight, crossLineHeight, crossLineWidth) withBackgroundColor:crossColor];
    [self insertLayerWithFrame:CGRectMake(leftWith + lightWidth - crossLineWidth, topHeight, crossLineWidth, crossLineHeight) withBackgroundColor:crossColor];
    
    [self insertLayerWithFrame:CGRectMake(leftWith, topHeight + lightHeight - crossLineHeight, crossLineWidth, crossLineHeight) withBackgroundColor:crossColor];
    [self insertLayerWithFrame:CGRectMake(leftWith, topHeight + lightHeight - crossLineWidth, crossLineHeight, crossLineWidth) withBackgroundColor:crossColor];
    
    [self insertLayerWithFrame:CGRectMake(leftWith + lightWidth - crossLineHeight, topHeight + lightHeight - crossLineWidth, crossLineHeight, crossLineWidth) withBackgroundColor:crossColor];
    [self insertLayerWithFrame:CGRectMake(leftWith + lightWidth - crossLineWidth, topHeight + lightHeight - crossLineHeight, crossLineWidth, crossLineHeight) withBackgroundColor:crossColor];
}

-(void)initScanCode {
    @autoreleasepool {
        _captureDevice = [ AVCaptureDevice defaultDeviceWithMediaType : AVMediaTypeVideo];
        _captureInput = [ AVCaptureDeviceInput deviceInputWithDevice : _captureDevice error : nil ];
        _captureOutput = [[ AVCaptureMetadataOutput alloc ] init ];
        [_captureOutput setMetadataObjectsDelegate : self queue : dispatch_get_main_queue ()];
        if (_isRectScan) {
            CGRect screenRect = [UIScreen mainScreen].bounds;
            [ _captureOutput setRectOfInterest : CGRectMake (topHeight / screenRect.size.height, leftWith / screenRect.size.width, lightHeight/screenRect.size.height, lightWidth / screenRect.size.width)];
        }

        _captureSession = [[ AVCaptureSession alloc ] init ];
        [_captureSession setSessionPreset : AVCaptureSessionPresetHigh ];
        if ([_captureSession canAddInput : _captureInput ])
        {
            [_captureSession addInput : _captureInput ];
        }
        if ([_captureSession canAddOutput : _captureOutput ])
        {
            [_captureSession addOutput : _captureOutput ];
        }
        _captureOutput.metadataObjectTypes = @[AVMetadataObjectTypeQRCode ] ;
        
        _capturePreview =[ AVCaptureVideoPreviewLayer layerWithSession :_captureSession ];
        _capturePreview.videoGravity = AVLayerVideoGravityResizeAspectFill ;
        _capturePreview.frame = self.view.layer.bounds ;
        [self.view.layer insertSublayer : _capturePreview atIndex : 0 ];
        [_captureSession startRunning ];
    }
}

- ( void )captureOutput:( AVCaptureOutput *)captureOutput didOutputMetadataObjects:( NSArray *)metadataObjects fromConnection:( AVCaptureConnection *)connection
{
    if (metadataObjects != nil && [metadataObjects count] > 0) {
        AVMetadataMachineReadableCodeObject *metadataObj = [metadataObjects objectAtIndex:0];
        NSString *scanCodeResult;
        if ([[metadataObj type] isEqualToString:AVMetadataObjectTypeQRCode]) {
            [self stopScanCode];
            scanCodeResult = metadataObj.stringValue;
            //回调信息
            if (_delegate && [_delegate respondsToSelector:@selector(scanCodeResultByViewController:withScanCodeResult:)]) {
                [_delegate scanCodeResultByViewController:self withScanCodeResult:scanCodeResult];
                [self.navigationController popViewControllerAnimated:YES];
            }
        } else {
            NSLog(@"扫描信息错误!");
        }
    }
}

- (void)systemFlashLight
{
#if !TARGET_IPHONE_SIMULATOR
    if([_captureDevice hasTorch] && [self.captureDevice hasFlash])
    {
        [_captureSession beginConfiguration];
        [_captureDevice lockForConfiguration:nil];
        if(_captureDevice.torchMode == AVCaptureTorchModeOff)
        {
            _flashLightBtn.selected = YES;
            [_captureDevice setTorchMode:AVCaptureTorchModeOn];
            [_captureDevice setFlashMode:AVCaptureFlashModeOn];
        }
        else {
            _flashLightBtn.selected = NO;
            [_captureDevice setTorchMode:AVCaptureTorchModeOff];
            [_captureDevice setFlashMode:AVCaptureFlashModeOff];
        }
        [_captureDevice unlockForConfiguration];
        [_captureSession commitConfiguration];
    }
#else
    [CommonUtil showAlert:G_ALERTTITLE withMessage:@"虚拟设备不能运行摄像头!"];
#endif
}

-(void)stopScanCode {
    [_captureSession stopRunning];
    _captureSession = nil;
    _captureDevice = nil;
    _captureInput = nil;
    _captureOutput = nil;
    [_capturePreview removeFromSuperlayer];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
}

@end


版权所有:半 饱 开发专栏
版本转载:http://blog.youkuaiyun.com/banbaodevelop
ps:如有转载请加以上信息
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值