iOS扫描二维码和生成二维码
2016-07-28 00:00
656 查看
摘要: 依赖系统框架实现扫描二维码和生成二维码
废话不多说,直接上代码
创建QRTool(生成二维码工具类)
生成二维码调用:
UIImage* img =[QRTool createQRImgWithContent:@"http://www.baidu.com" imgSize:200];
创建ScanQR(扫描二维码类)
创建QRView 扫描区域
扫描调用示例
废话不多说,直接上代码
创建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]; }
相关文章推荐
- 马化腾亲自“站台” 企业微信和个人微信互通能带来什么?
- 批处理制作二维码生成器
- 二维码的生成细节和原理
- jQuery qrcode生成二维码的方法
- 使用jquery.qrcode.min.js实现中文转化二维码
- jquery插件qrcode在线生成二维码
- JavaScript生成二维码图片小结
- php制作中间带自己定义图片二维码的方法
- zbar解码二维码和条形码示例
- php使用qr生成二维码的示例分享
- php实现扫描二维码根据浏览器类型访问不同下载地址
- PHP微信开发之二维码生成类
- asp.net(C#)使用QRCode生成图片中心加Logo或图像的二维码实例
- PHP QRCODE生成彩色二维码的方法
- Jquery 类网页微信二维码图块滚动效果具体实现
- Android仿微信二维码和条形码
- 微信QQ的二维码登录原理js代码解析
- ASP.NET生成二维码的方法总结
- 使用PHP生成二维码的方法汇总
- Perl生成纯HTML代码二维码实例