IOS生成二维码、扫二维码
2016-01-01 15:00
351 查看
有好多生成二维码以及扫二维码的第三方库,我这种方法是用系统自带的,他有个缺点就是生成的二维码太模糊,我这里进行了处理,遍历整个像素,对二维码进行颜色填充,使黑色加深
下面两个方法是处理二维码颜色的
运行效果:
中间的头像是叠在二维码上的,不会影响扫描结果,这里很简单就不共享代码了
遵守协议
一、生成二维码
//1. 创建二维码滤镜 CIFilter *filer = [CIFilter filterWithName:@"CIQRCodeGenerator"]; //2.还原滤镜的初始设置 [filer setDefaults]; //3.将要隐藏在二维码中的字符串变成data NSData *data = [@"123456" dataUsingEncoding:NSUTF8StringEncoding]; [filer setValue:data forKey:@"inputMessage"]; //5.生成二维码 CIImage *outputImage = [filer outputImage]; UIImage *image=[self createNonInterpolatedUIImageFormCIImage:outputImage withSize:250.0f]; //6.填充颜色后的二维码 codeImage =[self imageBlackToTransparent:image];
下面两个方法是处理二维码颜色的
#pragma mark - 二维码图片 //返回需要大小的UIImage - (UIImage *)createNonInterpolatedUIImageFormCIImage:(CIImage *)image withSize:(CGFloat) size { CGRect extent = CGRectIntegral(image.extent); CGFloat scale = MIN(size/CGRectGetWidth(extent), size/CGRectGetHeight(extent)); // 创建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); // 保存bitmap到图片 CGImageRef scaledImage = CGBitmapContextCreateImage(bitmapRef); return [UIImage imageWithCGImage:scaledImage]; } void ProviderReleaseData (void *info, const void *data, size_t size){ free((void*)data); } //对二维码进行颜色填充 - (UIImage*)imageBlackToTransparent:(UIImage*)image{ const int imageWidth = image.size.width; const int imageHeight = image.size.height; size_t bytesPerRow = imageWidth * 4; uint32_t* rgbImageBuf = (uint32_t*)malloc(bytesPerRow * imageHeight); // create context CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); CGContextRef context = CGBitmapContextCreate(rgbImageBuf, imageWidth, imageHeight, 8, bytesPerRow, colorSpace, kCGBitmapByteOrder32Little | kCGImageAlphaNoneSkipLast); CGContextDrawImage(context, CGRectMake(0, 0, imageWidth, imageHeight), image.CGImage); // 输出图片 CGDataProviderRef dataProvider = CGDataProviderCreateWithData(NULL, rgbImageBuf, bytesPerRow * imageHeight, ProviderReleaseData); CGImageRef imageRef = CGImageCreate(imageWidth, imageHeight, 8, 32, bytesPerRow, colorSpace, kCGImageAlphaLast | kCGBitmapByteOrder32Little, dataProvider, NULL, true, kCGRenderingIntentDefault); CGDataProviderRelease(dataProvider); UIImage* resultUIImage = [UIImage imageWithCGImage:imageRef]; return resultUIImage; }
运行效果:
中间的头像是叠在二维码上的,不会影响扫描结果,这里很简单就不共享代码了
二、扫二维码
导入#import <AVFoundation/AVFoundation.h>
遵守协议
<AVCaptureMetadataOutputObjectsDelegate>
// // ScanQRCodeViewController.h // IM // // Created by admin on 15/12/18. // Copyright © 2015年 ZBY. All rights reserved. // #import "BaseViewController.h" #import <AVFoundation/AVFoundation.h> @interface ScanQRCodeViewController : BaseViewController <AVCaptureMetadataOutputObjectsDelegate> @property (strong, nonatomic) UIView *viewPreview; @property (strong, nonatomic) UILabel *lblStatus; @property (strong, nonatomic) UIButton *startBtn; @property (strong, nonatomic) UIView *boxView; @property (nonatomic) BOOL isReading; @property (strong, nonatomic) CALayer *scanLayer; -(BOOL)startReading; -(void)stopReading; //捕捉会话 @property (nonatomic, strong) AVCaptureSession *captureSession; //展示layer @property (nonatomic, strong) AVCaptureVideoPreviewLayer *videoPreviewLayer; @end
// // ScanQRCodeViewController.m // IM // // Created by admin on 15/12/18. // Copyright © 2015年 ZBY. All rights reserved. // #import "ScanQRCodeViewController.h" #import "AddContactsViewController.h" #define SCANVIEW_EdgeTop 50.0 #define SCANVIEW_EdgeLeft 50.0 #define TINTCOLOR_ALPHA 0.4 //浅色透明度 #define DARKCOLOR_ALPHA 1 //深色透明度 @interface ScanQRCodeViewController () @end @implementation ScanQRCodeViewController - (void)viewDidLoad { [super viewDidLoad]; [self initBar:@"设置" titleName:@"扫描二维码"]; _viewPreview = [[UIView alloc]initWithFrame:CGRectMake(0, 64, WIDTH, HEIGHT-204)]; [self.view addSubview:_viewPreview]; _startBtn = [[UIButton alloc] initWithFrame:CGRectMake(0, HEIGHT-140, WIDTH, 40)]; [_startBtn setTitle:@"开始扫描" forState:UIControlStateNormal]; _startBtn.backgroundColor = MYCOLOR; [_startBtn addTarget:self action:@selector(startStopReading:) forControlEvents:UIControlEventTouchUpInside]; [self.view addSubview:_startBtn]; _lblStatus = [[UILabel alloc] initWithFrame:CGRectMake(10, HEIGHT-100, WIDTH-20, 100)]; //_lblStatus.backgroundColor = [UIColor whiteColor]; _lblStatus.numberOfLines = 0; _lblStatus.textAlignment = NSTextAlignmentCenter; _lblStatus.font = [UIFont systemFontOfSize:15]; [self.view addSubview:_lblStatus]; _captureSession = nil; _isReading = NO; [self startReading]; } - (BOOL)startReading { NSError *error; //1.初始化捕捉设备(AVCaptureDevice),类型为AVMediaTypeVideo AVCaptureDevice *captureDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; //2.用captureDevice创建输入流 AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:captureDevice error:&error]; if (!input) { NSLog(@"%@", [error localizedDescription]); return NO; } //3.创建媒体数据输出流 AVCaptureMetadataOutput *captureMetadataOutput = [[AVCaptureMetadataOutput alloc] init]; //4.实例化捕捉会话 _captureSession = [[AVCaptureSession alloc] init]; //4.1.将输入流添加到会话 [_captureSession addInput:input]; //4.2.将媒体输出流添加到会话中 [_captureSession addOutput:captureMetadataOutput]; //5.创建串行队列,并加媒体输出流添加到队列当中 dispatch_queue_t dispatchQueue; dispatchQueue = dispatch_queue_create("myQueue", NULL); //5.1.设置代理 [captureMetadataOutput setMetadataObjectsDelegate:self queue:dispatchQueue]; //5.2.设置输出媒体数据类型为QRCode [captureMetadataOutput setMetadataObjectTypes:[NSArray arrayWithObject:AVMetadataObjectTypeQRCode]]; //6.实例化预览图层 _videoPreviewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:_captureSession]; //7.设置预览图层填充方式 [_videoPreviewLayer setVideoGravity:AVLayerVideoGravityResizeAspectFill]; //8.设置图层的frame [_videoPreviewLayer setFrame:_viewPreview.layer.bounds]; //9.将图层添加到预览view的图层上 [_viewPreview.layer addSublayer:_videoPreviewLayer]; //10.设置扫描范围 captureMetadataOutput.rectOfInterest = CGRectMake(0.2f, 0.2f, 0.8f, 0.8f); //10.1.扫描框 _boxView = [[UIView alloc] initWithFrame:CGRectMake(40, (HEIGHT-204)/4, WIDTH-80, (HEIGHT-204)/2)]; _boxView.layer.borderColor = [UIColor greenColor].CGColor; _boxView.layer.borderWidth = 1.0f; [_viewPreview addSubview:_boxView]; //10.2.扫描线 _scanLayer = [[CALayer alloc] init]; _scanLayer.frame = CGRectMake(0, 0, _boxView.bounds.size.width, 1); _scanLayer.backgroundColor = [UIColor brownColor].CGColor; [_boxView.layer addSublayer:_scanLayer]; NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:0.2f target:self selector:@selector(moveScanLayer:) userInfo:nil repeats:YES]; [timer fire]; //10.开始扫描 [_captureSession startRunning]; return YES; } //实现AVCaptureMetadataOutputObjectsDelegate协议方法 #pragma mark - AVCaptureMetadataOutputObjectsDelegate - (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection { //判断是否有数据 if (metadataObjects != nil && [metadataObjects count] > 0) { AVMetadataMachineReadableCodeObject *metadataObj = [metadataObjects objectAtIndex:0]; //停止扫描 [self performSelectorOnMainThread:@selector(stopReading) withObject:nil waitUntilDone:NO]; NSLog(@"账号=%@",[metadataObj stringValue]); //扫一扫加好友 //判断回传的数据类型 if ([[metadataObj type] isEqualToString:AVMetadataObjectTypeQRCode]) { [_lblStatus performSelectorOnMainThread:@selector(setText:) withObject:@"正在添加好友" waitUntilDone:NO]; _isReading = NO; //添加联系人 dispatch_async(dispatch_get_main_queue(), ^{ [self addContacts:[metadataObj stringValue]]; }); } } } #pragma mark 添加联系人 -(void)addContacts:(NSString *)account{ AddContactsViewController *addController=[[AddContactsViewController alloc]init]; addController.userAccount=account; addController.onControllerTitle=@"扫一扫"; [self.navigationController pushViewController:addController animated:YES]; } - (void)moveScanLayer:(NSTimer *)timer { CGRect frame = _scanLayer.frame; if (_boxView.frame.size.height < _scanLayer.frame.origin.y) { frame.origin.y = 0; _scanLayer.frame = frame; }else{ frame.origin.y += 5; [UIView animateWithDuration:0.1 animations:^{ _scanLayer.frame = frame; }]; } } - (void)startStopReading:(id)sender { if (!_isReading) { if ([self startReading]) { [_startBtn setTitle:@"停止扫描" forState:UIControlStateNormal]; [_lblStatus setText:@"正在扫描..."]; } } else{ [self stopReading]; [_startBtn setTitle:@"开始扫描" forState:UIControlStateNormal]; } _isReading = !_isReading; } -(void)stopReading{ [_captureSession stopRunning]; _captureSession = nil; [_scanLayer removeFromSuperlayer]; [_videoPreviewLayer removeFromSuperlayer]; } -(void)viewWillAppear:(BOOL)animated{ [_startBtn setTitle:@"开始扫描" forState:UIControlStateNormal]; [_lblStatus performSelectorOnMainThread:@selector(setText:) withObject:@"" waitUntilDone:NO]; } @end
相关文章推荐
- 峰回路转,Firefox 浏览器即将重返 iOS 平台
- 峰回路转,Firefox 浏览器即将重返 iOS 平台
- 不可修补的 iOS 漏洞可能导致 iPhone 4s 到 iPhone X 永久越狱
- iOS 12.4 系统遭黑客破解,漏洞危及数百万用户
- 每日安全资讯:NSO,一家专业入侵 iPhone 的神秘公司
- [转][源代码]Comex公布JailbreakMe 3.0源代码
- 批处理制作二维码生成器
- jquery插件qrcode在线生成二维码
- JavaScript生成二维码图片小结
- php制作中间带自己定义图片二维码的方法
- zbar解码二维码和条形码示例
- php使用qr生成二维码的示例分享
- php实现扫描二维码根据浏览器类型访问不同下载地址
- PHP微信开发之二维码生成类
- 讲解iOS开发中基本的定位功能实现
- js判断客户端是iOS还是Android等移动终端的方法
- IOS开发环境windows化攻略
- 浅析iOS应用开发中线程间的通信与线程安全问题
- 检测iOS设备是否越狱的方法