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

iOS扫描二维码和生成二维码

2016-07-28 00:00 656 查看
摘要: 依赖系统框架实现扫描二维码和生成二维码

废话不多说,直接上代码
创建QRTool(生成二维码工具类)

#import <UIKit/UIKit.h>
@interface QRTool : NSObject
/**
*  生成二维码
*
*  @param qrContent 二维码内容
*  @param imgSize   二维码尺寸
*
*  @return 返回生成的二维码图片
*/
+(UIImage*)createQRImgWithContent:(NSString*)qrContent imgSize:(CGFloat)imgSize;
@end

#import "QRTool.h"
#import <CoreImage/CoreImage.h>

@implementation QRTool

+(UIImage *)createQRImgWithContent:(NSString *)qrContent imgSize :(CGFloat)imgSize{

CIFilter* filter = [CIFilter filterWithName:@"CIQRCodeGenerator"];
[filter setDefaults];

NSData* data = [qrContent dataUsingEncoding:NSUTF8StringEncoding];
[filter setValue:data forKeyPath:@"inputMessage"];
CIImage* outImg = [filter outputImage];

if (!imgSize) {
imgSize = 200;
}
return [self createNonInterpolatedUIImageFormCIImage:outImg withSize:imgSize];
}

/**
*  根据CIImage生成指定大小的UIImage
*
*  @param image CIImage
*  @param size  图片宽度
*/
+ (UIImage *)createNonInterpolatedUIImageFormCIImage:(CIImage *)image withSize:(CGFloat) size
{
CGRect extent = CGRectIntegral(image.extent);
CGFloat scale = MIN(size/CGRectGetWidth(extent), size/CGRectGetHeight(extent));

// 1.创建bitmap;
size_t width = CGRectGetWidth(extent) * scale;
size_t height = CGRectGetHeight(extent) * scale;
CGColorSpaceRef cs = CGColorSpaceCreateDeviceGray();
CGContextRef bitmapRef = CGBitmapContextCreate(nil, width, height, 8, 0, cs, (CGBitmapInfo)kCGImageAlphaNone);
CIContext *context = [CIContext contextWithOptions:nil];
CGImageRef bitmapImage = [context createCGImage:image fromRect:extent];
CGContextSetInterpolationQuality(bitmapRef, kCGInterpolationNone);
CGContextScaleCTM(bitmapRef, scale, scale);
CGContextDrawImage(bitmapRef, extent, bitmapImage);

// 2.保存bitmap到图片
CGImageRef scaledImage = CGBitmapContextCreateImage(bitmapRef);
CGContextRelease(bitmapRef);
CGImageRelease(bitmapImage);
return [UIImage imageWithCGImage:scaledImage];
}

生成二维码调用:
UIImage* img =[QRTool createQRImgWithContent:@"http://www.baidu.com" imgSize:200];

创建ScanQR(扫描二维码类)

#import <UIKit/UIKit.h>
@protocol scanResultDelegate <NSObject>
-(void)getScanResult:(NSString*)scanResult;
@end

@interface ScanQR : UIViewController
/** 扫描结果代理 */
@property(nonatomic,weak) id<scanResultDelegate> scanDelegate;
/**
*  扫描二维码
*/
-(void)scanQR;
@end

#import "ScanQR.h"
#import "QRView.h"
#import <AVFoundation/AVFoundation.h>

@interface ScanQR ()<AVCaptureMetadataOutputObjectsDelegate>

@property (strong, nonatomic) AVCaptureSession *session;
@property (strong, nonatomic) AVCaptureDevice * device;
@property (strong, nonatomic) AVCaptureDeviceInput * input;
@property (strong, nonatomic) AVCaptureMetadataOutput * output;
/** 预览区 */
@property (strong, nonatomic) AVCaptureVideoPreviewLayer *preview;

@property (nonatomic,weak) QRView *qrView;
@end

@implementation ScanQR

- (void)viewDidLoad {
[super viewDidLoad];
[self scanQR];
}

-(void)scanQR{
AVAuthorizationStatus status = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
if (status == AVAuthorizationStatusAuthorized) {
//授权

}else if(status == AVAuthorizationStatusNotDetermined){
//未决定
}else{
//拒绝----弹窗提示跳转设置权限
/*
if ([[[UIDevice currentDevice]systemVersion]floatValue]>=8.0) {
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString]];
}else{
NSURL*url=[NSURL URLWithString:@"prefs:root=Privacy"];
[[UIApplication sharedApplication] openURL:url];
}
*/
return;
}

_device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];

// Input
_input = [AVCaptureDeviceInput deviceInputWithDevice:self.device error:nil];

// Output
_output = [[AVCaptureMetadataOutput alloc]init];
[_output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];

// Session
_session = [[AVCaptureSession alloc]init];
[_session setSessionPreset:AVCaptureSessionPresetHigh];
if ([_session canAddInput:self.input])
{
[_session addInput:self.input];
}

if ([_session canAddOutput:self.output])
{
[_session addOutput:self.output];
}

//增加条形码扫描
// 条码类型 AVMetadataObjectTypeQRCode
//_output.metadataObjectTypes =@[AVMetadataObjectTypeQRCode];
_output.metadataObjectTypes = @[AVMetadataObjectTypeEAN13Code,
AVMetadataObjectTypeEAN8Code,
AVMetadataObjectTypeCode128Code,
AVMetadataObjectTypeQRCode];

// Preview
_preview =[AVCaptureVideoPreviewLayer layerWithSession:_session];
_preview.videoGravity =AVLayerVideoGravityResizeAspectFill;
_preview.frame =self.view.layer.bounds;

[self.view.layer insertSublayer:_preview atIndex:0];

[_session startRunning];

CGFloat screenHeight = [UIScreen mainScreen].bounds.size.height;
CGFloat screenWidth = [UIScreen mainScreen].bounds.size.width;

CGRect screenRect = [UIScreen mainScreen].bounds;

QRView *qrRectView = [[QRView alloc] initWithFrame:screenRect];

CGFloat qrvX = 240;
CGFloat qrvY = 240;

qrRectView.transparentArea = CGSizeMake(qrvX, qrvY);
qrRectView.backgroundColor = [UIColor clearColor];
qrRectView.center = CGPointMake(screenWidth/ 2, screenHeight/ 2);
[self.view addSubview:qrRectView];
self.qrView = qrRectView;

CGFloat cropY = (screenHeight - qrvY) / 2-120;
if (screenHeight == 480) {
cropY = (screenHeight - qrvY) / 2 - 60;
}

//修正扫描区域
CGRect cropRect = CGRectMake((screenWidth - qrRectView.transparentArea.width) / 2,
cropY,
qrvX,
qrvY);

[_output setRectOfInterest:CGRectMake(cropRect.origin.y / screenHeight,
cropRect.origin.x / screenWidth,
cropRect.size.height / screenHeight,
cropRect.size.width / screenWidth)];

}

#pragma mark - 实现output的回调方法
// 当扫描到数据时就会执行该方法
- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection
{
if (metadataObjects.count > 0) {
// 停止扫描
[self.session stopRunning];
[self.qrView stopAnimation];

//震动提示
AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);

AVMetadataMachineReadableCodeObject *object = [metadataObjects lastObject];

[self getResult:object.stringValue];
[self.navigationController popViewControllerAnimated:YES];
} else {
NSLog(@"没有扫描到数据");
}
}

-(void)getResult:(NSString*)result{
if ([self.scanDelegate respondsToSelector:@selector(getScanResult:)]) {
[self.scanDelegate getScanResult:result];
}
}

创建QRView 扫描区域

#import <UIKit/UIKit.h>
@interface QRView : UIView
/**
*  透明的区域
*/
@property (nonatomic, assign) CGSize transparentArea;
//结束动画
-(void)stopAnimation;
@end

#import "QRView.h"
static NSTimeInterval kQrLineanimateDuration = 0.02;

@implementation QRView {
UIImageView *qrLine;
CGFloat qrLineY;
UIButton *topBarView;
NSTimer *timer;
}

- (void)layoutSubviews {
[super layoutSubviews];
if (!qrLine) {
[self initQRLine];
timer = [NSTimer scheduledTimerWithTimeInterval:kQrLineanimateDuration target:self selector:@selector(show) userInfo:nil repeats:YES];
[timer fire];
}
}

- (void)initQRLine {

CGFloat w = self.transparentArea.width;
CGFloat h = self.transparentArea.height;

qrLine  = [[UIImageView alloc] initWithFrame:CGRectMake((self.bounds.size.width - w) / 2, (self.bounds.size.height - h) / 2, w, 2)];
//需要一张扫描线的图片,上下扫描
qrLine.image = [UIImage imageNamed:@"qr_scan_line"];

qrLine.contentMode = UIViewContentModeScaleAspectFill;
[self addSubview:qrLine];
//iPhone4 适配
if ([UIScreen mainScreen].bounds.size.height == 480) {
//iphone4s
qrLineY = qrLine.frame.origin.y+50;
}else{
qrLineY = qrLine.frame.origin.y;
}
}

- (void)show {
[UIView animateWithDuration:kQrLineanimateDuration animations:^{
CGRect rect = qrLine.frame;
rect.origin.y = qrLineY;
qrLine.frame = rect;
} completion:^(BOOL finished) {
CGFloat maxBorder = self.frame.size.height / 2 + self.transparentArea.height / 2 - 4-90;

if ([UIScreen mainScreen].bounds.size.height == 480) {
//iphone4s
maxBorder = maxBorder +50;
}

if (qrLineY > maxBorder) {
if ([UIScreen mainScreen].bounds.size.height == 480) {
/** 扫描框起点 */
qrLineY = self.frame.size.height / 2 - self.transparentArea.height /2-110+70;
}else{
qrLineY = self.frame.size.height / 2 - self.transparentArea.height /2-90;
}
}
qrLineY++;
}];
}

- (void)drawRect:(CGRect)rect {

//整个二维码扫描界面的颜色
CGSize screenSize =[UIScreen mainScreen].bounds.size;
CGRect screenDrawRect =CGRectMake(0, 0, screenSize.width,screenSize.height);

//中间清空的矩形框
CGRect clearDrawRect = CGRectMake(screenDrawRect.size.width / 2 - self.transparentArea.width / 2,
screenDrawRect.size.height / 2 - self.transparentArea.height / 2-90,
self.transparentArea.width,self.transparentArea.height);

CGContextRef ctx = UIGraphicsGetCurrentContext();
[self addScreenFillRect:ctx rect:screenDrawRect];
[self addCenterClearRect:ctx rect:clearDrawRect];
[self addWhiteRect:ctx rect:clearDrawRect];
[self addCornerLineWithContext:ctx rect:clearDrawRect];
}

- (void)addScreenFillRect:(CGContextRef)ctx rect:(CGRect)rect {

CGContextSetRGBFillColor(ctx, 40 / 255.0,40 / 255.0,40 / 255.0,0.5);
CGContextFillRect(ctx, rect);   //draw the transparent layer
}

- (void)addCenterClearRect :(CGContextRef)ctx rect:(CGRect)rect {
//iPhone4 适配
if ([UIScreen mainScreen].bounds.size.height == 480) {
rect = CGRectMake(rect.origin.x, rect.origin.y +50, rect.size.width, rect.size.height);
}
CGContextClearRect(ctx, rect);  //clear the center rect  of the layer
}

- (void)addWhiteRect:(CGContextRef)ctx rect:(CGRect)rect {
//iPhone4 适配
if ([UIScreen mainScreen].bounds.size.height == 480) {
rect = CGRectMake(rect.origin.x, rect.origin.y +50, rect.size.width, rect.size.height);
}
CGContextStrokeRect(ctx, rect);
CGContextSetRGBStrokeColor(ctx, 1, 1, 1, 1);
CGContextSetLineWidth(ctx, 0.8);
CGContextAddRect(ctx, rect);
CGContextStrokePath(ctx);
}

- (void)addCornerLineWithContext:(CGContextRef)ctx rect:(CGRect)rect{
//iPhone4 适配
if ([UIScreen mainScreen].bounds.size.height == 480) {
rect = CGRectMake(rect.origin.x, rect.origin.y +50, rect.size.width, rect.size.height);
}
//画四个边角
CGContextSetLineWidth(ctx, 2);
CGContextSetRGBStrokeColor(ctx, 83 /255.0, 239/255.0, 111/255.0, 1);//绿色

//左上角
CGPoint poinsTopLeftA[] = {
CGPointMake(rect.origin.x+0.7, rect.origin.y),
CGPointMake(rect.origin.x+0.7 , rect.origin.y + 15)
};

CGPoint poinsTopLeftB[] = {CGPointMake(rect.origin.x, rect.origin.y +0.7),CGPointMake(rect.origin.x + 15, rect.origin.y+0.7)};
[self addLine:poinsTopLeftA pointB:poinsTopLeftB ctx:ctx];

//左下角
CGPoint poinsBottomLeftA[] = {CGPointMake(rect.origin.x+ 0.7, rect.origin.y + rect.size.height - 15),CGPointMake(rect.origin.x +0.7,rect.origin.y + rect.size.height)};
CGPoint poinsBottomLeftB[] = {CGPointMake(rect.origin.x , rect.origin.y + rect.size.height - 0.7) ,CGPointMake(rect.origin.x+0.7 +15, rect.origin.y + rect.size.height - 0.7)};
[self addLine:poinsBottomLeftA pointB:poinsBottomLeftB ctx:ctx];

//右上角
CGPoint poinsTopRightA[] = {CGPointMake(rect.origin.x+ rect.size.width - 15, rect.origin.y+0.7),CGPointMake(rect.origin.x + rect.size.width,rect.origin.y +0.7 )};
CGPoint poinsTopRightB[] = {CGPointMake(rect.origin.x+ rect.size.width-0.7, rect.origin.y),CGPointMake(rect.origin.x + rect.size.width-0.7,rect.origin.y + 15 +0.7 )};
[self addLine:poinsTopRightA pointB:poinsTopRightB ctx:ctx];

CGPoint poinsBottomRightA[] = {CGPointMake(rect.origin.x+ rect.size.width -0.7 , rect.origin.y+rect.size.height+ -15),CGPointMake(rect.origin.x-0.7 + rect.size.width,rect.origin.y +rect.size.height )};
CGPoint poinsBottomRightB[] = {CGPointMake(rect.origin.x+ rect.size.width - 15 , rect.origin.y + rect.size.height-0.7),CGPointMake(rect.origin.x + rect.size.width,rect.origin.y + rect.size.height - 0.7 )};
[self addLine:poinsBottomRightA pointB:poinsBottomRightB ctx:ctx];
CGContextStrokePath(ctx);
}

- (void)addLine:(CGPoint[])pointA pointB:(CGPoint[])pointB ctx:(CGContextRef)ctx {
CGContextAddLines(ctx, pointA, 2);
CGContextAddLines(ctx, pointB, 2);
}
-(void)stopAnimation
{
[timer invalidate];
timer = nil;
}

扫描调用示例

// 1.实现代理
-(void)scan{
ScanQR *scan = [[ScanQR alloc]init];
scan.scanDelegate = self;
[self.navigationController pushViewController:scan animated:YES];
}

// 扫描代理方法---获取扫描结果
-(void)getScanResult:(NSString *)scanResult{
NSLog(@"扫描结果是:============%@",scanResult);
UIAlertView* alert = [[UIAlertView alloc]initWithTitle:@"扫描结果" message:scanResult delegate:nil cancelButtonTitle:nil otherButtonTitles:@"确定", nil];
[alert show];
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息