在iOS7之前,用來(lái)掃碼可以用第三方庫(kù),比如ZXingObjC。在iOS7之后,蘋(píng)果提供的方法就很方便且高效。
--掃碼--
//掃碼
-(void)scanBarcode
{
//初始化捕獲設(shè)備
AVCaptureDevice *device=[AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
//輸入流
AVCaptureDeviceInput *input=[AVCaptureDeviceInput deviceInputWithDevice:device error:nil];
if (!input) {
return;
}
//輸出流
AVCaptureMetadataOutput *output=[[AVCaptureMetadataOutput alloc]init];
//設(shè)置代理 ,主線程刷新
[output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
//自定義一個(gè)掃描區(qū)域
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));
//設(shè)置掃描框
[self setupScanAreaViewWithRect:scanWinRect];
//設(shè)置掃描捕捉數(shù)據(jù)的框 (此處的屏幕rect值的范圍是0-1,按照比例來(lái)計(jì)算)
output.rectOfInterest=[self getRectOfInterestWithScanWinRect:scanWinRect];
//初始化連接對(duì)象
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];
//開(kāi)始捕獲
[session startRunning];
}
在設(shè)置rectOfInterest值得時(shí)候要注意,它是按照屏幕橫屏來(lái)計(jì)算的,所以x軸和y軸要互換,同時(shí)注意取值范圍值【0-1】,按照屏幕比例計(jì)算。
- (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) {
//結(jié)束
[_session stopRunning];
//掃碼結(jié)果
AVMetadataMachineReadableCodeObject *readObject=[metadataObjects objectAtIndex:0];
NSLog(@"%@",readObject.stringValue);
}
}
--生成--
//1.二維碼濾鏡
CIFilter *filter=[CIFilter filterWithName:@"CIQRCodeGenerator"];
//2.設(shè)置濾鏡數(shù)據(jù)
[filter setValue:data forKey:@"inputMessage"];
//3.獲取濾鏡輸出的圖像
CIImage *outputImage=[filter outputImage];
//將圖放大
CGAffineTransform transform = CGAffineTransformMakeScale(6, 6); // scale 為放大倍數(shù)
CIImage *transformImage = [outputImage imageByApplyingTransform:transform];
//4.轉(zhuǎn)換成CGImage
CIContext *context=[CIContext contextWithOptions:nil];
CGImageRef imageRef = [context createCGImage:transformImage fromRect:transformImage.extent];
//5.轉(zhuǎn)換成UIImage
UIImage *qrCodeImage = [UIImage imageWithCGImage:imageRef];
- 生成的二維碼圖片模糊,可將其放大后顯示。
- 還可以通過(guò) [CIFilter filterWithName:keysAndValues:, nil] 此濾鏡方法修改二維碼顏色。
--讀取--
//初始化檢測(cè)器
CIDetector *detector=[CIDetector detectorOfType:CIDetectorTypeQRCode context:nil options:@{CIDetectorAccuracy:CIDetectorAccuracyHigh}];
//轉(zhuǎn)成CIImage
CIImage *ciimage=[CIImage imageWithCGImage:self.image.CGImage];
//檢測(cè)結(jié)果
NSArray *features =[detector featuresInImage:ciimage];
CIQRCodeFeature *feature=[features firstObject];
//打印
NSString *string=[feature messageString];