iOS開發(fā)-二維碼掃描

序言

之前做二維碼掃描有使用過ZBar, ZXing,并沒有覺得集成或者使用有多方便。iOS7之后,蘋果就提供了掃碼相關的接口,今天嘗試了下,掃碼的識別效率比較高,提供的API用起來也比較方便。本文主要說明:1. 使用原生API實現(xiàn)掃碼功能。2. 如何設置掃描范圍。3. 透明區(qū)域圖形繪制。

相關接口:

一個最簡單的二維碼掃描功能,需要用到如下這些類:
  1. AVCaptureDevice:物理設備,提供實時輸入的媒體數(shù)據(jù),如視頻和音頻
_device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
  1. AVCaptureDeviceInput:提供接口從AVCaptureDevice捕獲數(shù)據(jù)
  2. AVCaptureMetadataOutput:輸出類,輸出讀取的數(shù)據(jù)
  3. AVCaptureSession:關聯(lián)輸入輸出,信息實時輸入輸出的樞紐
  4. AVCaptureVideoPreviewLayer:顯示攝像頭捕獲的數(shù)據(jù)
掃碼功能初始化:
@property (strong,nonatomic) AVCaptureDevice *device;
@property (strong,nonatomic) AVCaptureDeviceInput *input;
@property (strong,nonatomic) AVCaptureMetadataOutput *output;
@property (strong,nonatomic) AVCaptureSession *session;
@property (strong,nonatomic) AVCaptureVideoPreviewLayer *previewLayer;
_device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
_input = [AVCaptureDeviceInput deviceInputWithDevice:self.device error:nil];
_output = [[AVCaptureMetadataOutput alloc]init];
[_output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];

_session = [[AVCaptureSession alloc]init];
[_session setSessionPreset:AVCaptureSessionPresetHigh];

if ([_session canAddInput:self.input]) {
    [_session addInput:self.input];
}
if ([_session canAddOutput:self.output])
{
    [_session addOutput:self.output];
}
_output.metadataObjectTypes = @[AVMetadataObjectTypeQRCode];
_previewLayer = [AVCaptureVideoPreviewLayer layerWithSession:_session];
_previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
_previewLayer.frame = self.view.layer.bounds;
[self.view.layer insertSublayer:_previewLayer atIndex:0];

[_session startRunning];
識別到二維碼信息后,代理方法會執(zhí)行,在此解析數(shù)據(jù):
- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection
{
    if ([metadataObjects count] >0)
    {
        [_session stopRunning];
        AVMetadataMachineReadableCodeObject * metadataObject = [metadataObjects objectAtIndex:0];
        NSString *stringValue = metadataObject.stringValue;
        NSLog(@"解析到的數(shù)據(jù) : %@",stringValue);
        NSURL *url = [NSURL URLWithString:stringValue];
        if([[UIApplication sharedApplication]canOpenURL:url])
        {
           [[UIApplication sharedApplication]openURL:url];
        }
    }
}

如上兩段代碼即可實現(xiàn)二維碼掃描功能。
但是我們會發(fā)現(xiàn)我們整個屏幕都是二維碼掃描的區(qū)域。如果有多個二維碼在一塊,這時可能會影響你掃碼的準確性。這個時候我們就需要設置掃描的識別區(qū)域了。

掃描范圍設置:

iOS也為我們提供了一個接口,可以設置識別區(qū)域。

@property(nonatomic) CGRect rectOfInterest;//默認值為CGRectMake(0, 0, 1, 1)

我們剛開始對此屬性進行設置時,可能發(fā)現(xiàn)怎么設置都不對。后面發(fā)現(xiàn)一個奇怪的現(xiàn)象:原點似乎是在右上角,而且對應的x和y的值好像也是反的。如下圖:

圖1

ABCD四點的值分別標記在了圖中。重點在A點,理解了A點,其余的幾個點也就都理解了。與上圖掃描區(qū)域?qū)膔ect設置為:

 _output.rectOfInterest = CGRectMake(0.35, 0.3, 0.6, 0.7);

如果還是不好理解這個坐標,那么請想象一下:假設你的手機是透明的,從二維碼所在的方位,看你的手機。從手機的背面看這個圖片,是不是和我們所理解的坐標系統(tǒng)(原點在左上)一樣了。

最后再附上一段, 繪制透明區(qū)域的代碼:

- (void)drawRect:(CGRect)rect {
    
    [[UIColor colorWithWhite:0 alpha:0.5] setFill];
    //半透明區(qū)域
    UIRectFill(rect);
    
    //透明的區(qū)域
    CGRect holeRection = CGRectMake(85,180,200,200);
    CGRect holeiInterSection = CGRectIntersection(holeRection, rect);
    [[UIColor clearColor] setFill];
    
    UIRectFill(holeiInterSection);
}```
最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容