在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()];
//自定義一個掃描區(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));
//設置掃描框
[self setupScanAreaViewWithRect:scanWinRect];
//設置掃描捕捉數(shù)據(jù)的框 (此處的屏幕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.設置濾鏡數(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];
- 生成的二維碼圖片模糊,可將其放大后顯示渔肩。
- 還可以通過 [CIFilter filterWithName:keysAndValues:, nil] 此濾鏡方法修改二維碼顏色因俐。
--讀取--
//初始化檢測器
CIDetector *detector=[CIDetector detectorOfType:CIDetectorTypeQRCode context:nil options:@{CIDetectorAccuracy:CIDetectorAccuracyHigh}];
//轉(zhuǎn)成CIImage
CIImage *ciimage=[CIImage imageWithCGImage:self.image.CGImage];
//檢測結果
NSArray *features =[detector featuresInImage:ciimage];
CIQRCodeFeature *feature=[features firstObject];
//打印
NSString *string=[feature messageString];