您的位置:首页 > 移动开发 > IOS开发

iOS二维码生成及扫码

2015-12-18 11:54 417 查看
概要
现在越来越多的应用加入二维码相关的业务,在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.csdn.net/banbaodevelop

ps:如有转载请加以上信息
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: