I. 二维码的生成模块
#import "CreatQRViewController.h"
//必须调用
#import <CoreImage/CoreImage.h>
@interface CreatQRViewController ()
@property (weak, nonatomic) IBOutlet UIImageView *QRCodeImgV; //生成二维码的UIImageView
@property (weak, nonatomic) IBOutlet UITextField *inputWordTF; //字符串输入框
/**生成二维码的方法*/
- (IBAction)createQRCode:(UIButton *)sender;
@end
@implementation CreatQRViewController
- (void)viewDidLoad {
[super viewDidLoad];
}
/**
* 根据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];
}
- (IBAction)createQRCode:(UIButton *)sender {
//1.实例化二维码滤镜
CIFilter *filter = [CIFilter filterWithName:@"CIQRCodeGenerator"];
//2.恢复滤镜的默认属性
[filter setDefaults];
//3.将字符串转化为NSData
NSString *string = self.inputWordTF.text;
NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding];
//4.通过KVO设置滤镜inputMessage数据
[filter setValue:data forKeyPath:@"inputMessage"];
//5.获得滤镜输出的图像
CIImage *outputImg = [filter outputImage];
//6.将CIImage转换为UIImage 并放大显示
self.QRCodeImgV.image = [self createNonInterpolatedUIImageFormCIImage:outputImg withSize:200];
}
@end
II. 二维码的扫描和识别模块
#import "ScanQRViewController.h"
//必须调用
#import <AVFoundation/AVFoundation.h>
@interface ScanQRViewController ()<AVCaptureMetadataOutputObjectsDelegate>
@property (nonatomic, strong) AVCaptureSession *session;
@property (nonatomic, strong) AVCaptureVideoPreviewLayer *layer;
@property (weak, nonatomic) IBOutlet UILabel *scanResults; //扫描结果
/**扫描及显示识别结果*/
- (IBAction)scanQRCode:(UIButton *)sender;
@end
@implementation ScanQRViewController
- (void)viewDidLoad {
[super viewDidLoad];
}
#pragma mark - 实现output的回调方法
- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection
{
if (metadataObjects.count > 0) {
AVMetadataMachineReadableCodeObject *obj = [metadataObjects lastObject];
//有数据的时候
self.scanResults.text = obj.stringValue;
[self.session stopRunning];
[self.layer removeFromSuperlayer];
}else {
//没数据的时候
self.scanResults.text = @"没有任何数据";
}
}
- (IBAction)scanQRCode:(UIButton *)sender {
AVCaptureSession *session = [[AVCaptureSession alloc] init];
self.session = session;
AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:device error:nil];
[session addInput:input];
AVCaptureMetadataOutput *output = [[AVCaptureMetadataOutput alloc] init];
[output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
[session addOutput:output];
[output setMetadataObjectTypes:@[AVMetadataObjectTypeQRCode]];
AVCaptureVideoPreviewLayer *layer = [AVCaptureVideoPreviewLayer layerWithSession:session];
layer.frame = self.view.bounds;
[self.view.layer addSublayer:layer];
self.layer = layer;
[session startRunning];
}
@end