在iOS7之前,用来扫码可以用第三方库,比如ZXingObjC。在iOS7之后,苹果提供的方法就很方便且高效。
--扫码--
//扫码
-(void)scanBarcode
{
//初始化捕获设备
AVCaptureDevice *device=[AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
//输入流
AVCaptureDeviceInput *input=[AVCaptureDeviceInput deviceInputWithDevice:device error:nil];
if (!input) {
return;
}
//输出流
AVCaptureMetadataOutput *output=[[AVCaptureMetadataOutput alloc]init];
//设置代理 ,主线程刷新
[output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
//自定义一个扫描区域
CGRect scanWinRect=CGRectMake(self.view.width/6, (self.view.height-self.view.width)/2+self.view.width/6, (self.view.width-self.view.width/3), (self.view.width-self.view.width/3));
//设置扫描框
[self setupScanAreaViewWithRect:scanWinRect];
//设置扫描捕捉数据的框 (此处的屏幕rect值的范围是0-1,按照比例来计算)
output.rectOfInterest=[self getRectOfInterestWithScanWinRect:scanWinRect];
//初始化连接对象
AVCaptureSession *session=[[AVCaptureSession alloc]init];
self.session=session;
[session setSessionPreset:AVCaptureSessionPresetHigh];
[session addInput:input];
[session addOutput:output];
//扫码支持的格式(二维码QR/条形码EAN)
output.metadataObjectTypes = @[AVMetadataObjectTypeQRCode,AVMetadataObjectTypeEAN13Code, AVMetadataObjectTypeEAN8Code, AVMetadataObjectTypeCode128Code];
AVCaptureVideoPreviewLayer *layer=[AVCaptureVideoPreviewLayer layerWithSession:session];
layer.videoGravity=AVLayerVideoGravityResizeAspectFill;
layer.frame=self.view.layer.bounds;
[self.view.layer insertSublayer:layer atIndex:0];
//开始捕获
[session startRunning];
}
在设置rectOfInterest值得时候要注意,它是按照屏幕横屏来计算的,所以x轴和y轴要互换,同时注意取值范围值【0-1】,按照屏幕比例计算。
- (CGRect)getRectOfInterestWithScanWinRect:(CGRect )rect
{
CGFloat x = rect.origin.x/self.view.width;
CGFloat y = rect.origin.y/self.view.height;
CGFloat width=rect.size.width/self.view.width;
CGFloat height=rect.size.height/self.view.height;
return CGRectMake(y, x, height, width);
}
代理方法:
-(void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection
{
if (metadataObjects.count>0) {
//结束
[_session stopRunning];
//扫码结果
AVMetadataMachineReadableCodeObject *readObject=[metadataObjects objectAtIndex:0];
NSLog(@"%@",readObject.stringValue);
}
}
--生成--
//1.二维码滤镜
CIFilter *filter=[CIFilter filterWithName:@"CIQRCodeGenerator"];
//2.设置滤镜数据
[filter setValue:data forKey:@"inputMessage"];
//3.获取滤镜输出的图像
CIImage *outputImage=[filter outputImage];
//将图放大
CGAffineTransform transform = CGAffineTransformMakeScale(6, 6); // scale 为放大倍数
CIImage *transformImage = [outputImage imageByApplyingTransform:transform];
//4.转换成CGImage
CIContext *context=[CIContext contextWithOptions:nil];
CGImageRef imageRef = [context createCGImage:transformImage fromRect:transformImage.extent];
//5.转换成UIImage
UIImage *qrCodeImage = [UIImage imageWithCGImage:imageRef];
- 生成的二维码图片模糊,可将其放大后显示。
- 还可以通过 [CIFilter filterWithName:keysAndValues:, nil] 此滤镜方法修改二维码颜色。
--读取--
//初始化检测器
CIDetector *detector=[CIDetector detectorOfType:CIDetectorTypeQRCode context:nil options:@{CIDetectorAccuracy:CIDetectorAccuracyHigh}];
//转成CIImage
CIImage *ciimage=[CIImage imageWithCGImage:self.image.CGImage];
//检测结果
NSArray *features =[detector featuresInImage:ciimage];
CIQRCodeFeature *feature=[features firstObject];
//打印
NSString *string=[feature messageString];