你好,歡迎來到IOS教程網

 Ios教程網 >> IOS編程開發 >> IOS開發基礎 >> 詳細易懂的二維碼的掃描、識別與生成

詳細易懂的二維碼的掃描、識別與生成

編輯:IOS開發基礎

ios7之前我們實現二維碼掃描是借助第三方(ZBar,ZXing等)來實現的,在ios7之後系統自己提供二維碼掃描的方法,性能也要比第三方更好。

今天就來介紹一下原生二維碼的使用,包括掃描二維碼,從圖片掃描二維碼和生成二維碼。講解中只展示部分代碼,具體請看Github Demo,裡面的代碼不多,也很容易看懂。

掃描二維碼

二維碼掃描需要用到AVFoundation.framework,需要用先創建一個AVCaptureSession,然後設置輸入輸出流,以及掃描區域和支持的格式:

//獲取攝像設備
AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
//創建輸入流
AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:device error:nil];
if (!input)
{
    return nil;
}
//創建輸出流
AVCaptureMetadataOutput *output = [[AVCaptureMetadataOutput alloc] init];
//設置代理 在主線程裡刷新
[output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
//設置掃描區域的比例
CGFloat width = 300 / CGRectGetHeight(self.view.frame);
CGFloat height = 300 / CGRectGetWidth(self.view.frame);
output.rectOfInterest = CGRectMake((1 - width) / 2, (1- height) / 2, width, height);

AVCaptureSession *session = [[AVCaptureSession alloc] init];
//高質量采集率
[session setSessionPreset:AVCaptureSessionPresetHigh];
[session addInput:input];
[session addOutput:output];

//設置掃碼支持的編碼格式(這裡設置條形碼和二維碼兼容)
output.metadataObjectTypes = @[AVMetadataObjectTypeQRCode,
                               AVMetadataObjectTypeEAN13Code,
                               AVMetadataObjectTypeEAN8Code,
                               AVMetadataObjectTypeCode128Code];

然後用這個session生成一個AVCaptureVideoPreviewLayer加到某個view的layer上,就可以實時顯示攝像頭捕捉的內容了:

AVCaptureVideoPreviewLayer *layer = [AVCaptureVideoPreviewLayer layerWithSession:self.session];
layer.videoGravity = AVLayerVideoGravityResizeAspectFill;
layer.frame = self.view.layer.bounds;
[self.view.layer insertSublayer:layer atIndex:0];

然後調用[self.session startRunning];開始捕獲,當掃描出結果後會調用下面的代理方法,其中metadataObject.stringValue就是掃描後的結果。

#pragma mark - AVCaptureMetadataOutputObjectsDelegate
-(void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection
{
    if (metadataObjects.count > 0)
    {        
        AVMetadataMachineReadableCodeObject *metadataObject = [metadataObjects firstObject];
    }

}

為了在黑夜也可以很好的掃描,可以設置一個閃光燈的開關:

#pragma mark - 開關閃光燈
- (void)rightBarButtonDidClick:(UIBarButtonItem *)item
{
    self.flashOpen = !self.flashOpen;

    AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];

    if ([device hasTorch] && [device hasFlash])
    {
        [device lockForConfiguration:nil];

        if (self.flashOpen)
        {
            device.torchMode = AVCaptureTorchModeOn;
            device.flashMode = AVCaptureFlashModeOn;
        }
        else
        {
            device.torchMode = AVCaptureTorchModeOff;
            device.flashMode = AVCaptureFlashModeOff;
        }

        [device unlockForConfiguration];
    }
}

1608265-268a61962145720c.png

掃描二維碼

從圖片掃描

有時候我們需要從圖片中掃描二維碼,或者從相冊選擇一張圖片,代碼如下,具體可以看demo。其中feature.messageString就是掃描後的結果。

- (void)findQRCodeFromImage:(UIImage *)image
{
    CIDetector *detector = [CIDetector detectorOfType:CIDetectorTypeQRCode
                                              context:nil
                                              options:@{CIDetectorAccuracy:CIDetectorAccuracyHigh}];

    NSArray *features = [detector featuresInImage:[CIImage imageWithCGImage:image.CGImage]];
    if (features.count >= 1)
    {
        CIQRCodeFeature *feature = [features firstObject];
    }
}

1608265-2b1fa03e6a50237b.gif

從圖片掃描

生成二維碼

生成二維碼的代碼很簡單,代碼如下。

/** 生成指定大小的黑白二維碼 */
- (UIImage *)createQRImageWithString:(NSString *)string size:(CGSize)size
{
    NSData *stringData = [string dataUsingEncoding:NSUTF8StringEncoding];

    CIFilter *qrFilter = [CIFilter filterWithName:@"CIQRCodeGenerator"];
    //    NSLog(@"%@",qrFilter.inputKeys);
    [qrFilter setValue:stringData forKey:@"inputMessage"];
    [qrFilter setValue:@"M" forKey:@"inputCorrectionLevel"];

    CIImage *qrImage = qrFilter.outputImage;
    //放大並繪制二維碼 (上面生成的二維碼很小,需要放大)
    CGImageRef cgImage = [[CIContext contextWithOptions:nil] createCGImage:qrImage fromRect:qrImage.extent];
    UIGraphicsBeginImageContext(size);
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetInterpolationQuality(context, kCGInterpolationNone);
    //翻轉一下圖片 不然生成的QRCode就是上下顛倒的
    CGContextScaleCTM(context, 1.0, -1.0);
    CGContextDrawImage(context, CGContextGetClipBoundingBox(context), cgImage);
    UIImage *codeImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    CGImageRelease(cgImage);

    return codeImage;
}

1608265-dc0ad3554614009f.png

黑白二維碼

上面默認生成的時黑白二維碼,不過我們也可以改顏色:

/** 為二維碼改變顏色 */
- (UIImage *)changeColorForQRImage:(UIImage *)image backColor:(UIColor *)backColor frontColor:(UIColor *)frontColor
{
    CIFilter *colorFilter = [CIFilter filterWithName:@"CIFalseColor"
                                       keysAndValues:
                             @"inputImage",[CIImage imageWithCGImage:image.CGImage],
                             @"inputColor0",[CIColor colorWithCGColor:frontColor.CGColor],
                             @"inputColor1",[CIColor colorWithCGColor:backColor.CGColor],
                             nil];

    return [UIImage imageWithCIImage:colorFilter.outputImage];
}

1608265-7211754266ea9998.png

為二維碼改變顏色

有的二維碼也會在中心加一個小圖片,例如用戶頭像,代碼如下:

/** 在二維碼中心加一個小圖 */
- (UIImage *)addSmallImageForQRImage:(UIImage *)qrImage
{
    UIGraphicsBeginImageContext(qrImage.size);
    [qrImage drawInRect:CGRectMake(0, 0, qrImage.size.width, qrImage.size.height)];
    UIImage *image = [UIImage imageNamed:@"small"];
    CGFloat imageW = 50;
    CGFloat imageX = (qrImage.size.width - imageW) * 0.5;
    CGFloat imgaeY = (qrImage.size.height - imageW) * 0.5;
    [image drawInRect:CGRectMake(imageX, imgaeY, imageW, imageW)];
    UIImage *result = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return result;
}

1608265-b904ed48d3a825fd.png

中心加小圖的二維碼

其實也可以掃描條形碼,大家可以對著條形碼試一試,代碼都是通用的。

  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved