你好,歡迎來到IOS教程網

 Ios教程網 >> IOS編程開發 >> IOS開發綜合 >> iOS 原生二維碼掃描(可限制掃描區域)

iOS 原生二維碼掃描(可限制掃描區域)

編輯:IOS開發綜合

寫這篇文章的主要原因不是展示如何使用 AVFoundation 來進行二維碼掃描,更主要的是限制掃描二維碼的范圍。(因為默認的是全屏掃描)

項目遇到掃描二維碼的功能需求,這裡我放棄了使用三方庫,而采用了蘋果原生的掃描。

原生的好處就是掃描特別快效率特別高,但是遇到一個問題就是不知道怎麼去限制掃描范圍。

還是先簡單說一下怎麼使用來進行二維碼掃描吧。


首先是要用到的幾個類

@property (strong,nonatomic)AVCaptureDevice * device;

@property (strong,nonatomic)AVCaptureDeviceInput * input;

@property (strong,nonatomic)AVCaptureMetadataOutput * output;

@property (strong,nonatomic)AVCaptureSession * session;

@property (strong,nonatomic)AVCaptureVideoPreviewLayer * preview;

他們之間的關系可以看下面的篇文章

傳送門


下面分別創建他們

// Device

_device = [AVCaptureDevicedefaultDeviceWithMediaType:AVMediaTypeVideo];

// Input

_input = [AVCaptureDeviceInputdeviceInputWithDevice:self.deviceerror:nil];

// Output

_output = [[AVCaptureMetadataOutputalloc]init];

[_outputsetMetadataObjectsDelegate:selfqueue:dispatch_get_main_queue()];


// Session

_session = [[AVCaptureSessionalloc]init];

[_sessionsetSessionPreset:AVCaptureSessionPresetHigh];

if ([_sessioncanAddInput:self.input])

{

[_sessionaddInput:self.input];

}

if ([_sessioncanAddOutput:self.output])

{

[_sessionaddOutput:self.output];

}

// 條碼類型 AVMetadataObjectTypeQRCode

_output.metadataObjectTypes =@[AVMetadataObjectTypeQRCode];


// Preview

_preview =[AVCaptureVideoPreviewLayerlayerWithSession:_session];

_preview.videoGravity =AVLayerVideoGravityResizeAspectFill;

_preview.frame =self.view.layer.bounds;

[self.view.layerinsertSublayer:_previewatIndex:0];


// Start

[_sessionstartRunning];


然後實現 AVCaptureMetadataOutputObjectsDelegate

#pragma mark AVCaptureMetadataOutputObjectsDelegate

- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection

{

NSString *stringValue;

if ([metadataObjectscount] >0)

{

//停止掃描

[_sessionstopRunning];

AVMetadataMachineReadableCodeObject * metadataObject = [metadataObjectsobjectAtIndex:0];

stringValue = metadataObject.stringValue;

}


}


到此為止就可以成功掃描二維碼了,但是有個尴尬的問題,這時的掃描是全屏掃描的。即

vc/CzuejrLDRy/nT0M/rtb21xLe9t6i2vMrUwcvSu7Hpo6y1q8rHtryyu9DQo6i2vMrHwOGjqaOs1+66872r0qq3xcb6tcTKsbryt6LP1sHL0ru49rHIvc+/ydLJtcS146GjPC9wPgo8cD48YnI+CjwvcD4KPHA+PC9wPgo8cD5AcHJvcGVydHkobm9uYXRvbWljKUNHUmVjdCByZWN0T2ZJbnRlcmVzdApOU19BVkFJTEFCTEVfSU9TKDdfMCk7PC9wPgrV4srHtcQgQVZDYXB0dXJlTWV0YWRhdGFPdXRwdXQg0ru49sr00NSjrMv8tcS94srNyscKCjxwPgpAZGlzY3Vzc2lvbjwvcD4KPHA+ClRoZSB2YWx1ZSBvZiB0aGlzIHByb3BlcnR5IGlzIGEgQ0dSZWN0IHRoYXQgZGV0ZXJtaW5lcyB0aGUgcmVjZWl2ZXI="s rectangle of interest for each frame of video.

The rectangle's origin is top left and is relative to the coordinate space of the device providing the metadata. Specifying

a rectOfInterest may improve detection performance for certain types of metadata. The default value of this property is the

value CGRectMake(0, 0, 1, 1). Metadata objects whose bounds do not intersect with the rectOfInterest will not be returned.


大概意思就是設置每一幀畫面感興趣的區域(字面意思),那豈不是就是設置掃描范圍喽,大喜 於是趕緊把rectOfInterest設置成中間框的frame,

[_outputsetRectOfInterest:CGRectMake((ScreenWidth-220)/2,60+64,220, 220)];

//中間區域的寬和高都是220 ScreenWidth為設備屏幕寬度

但是卻發現怎麼掃描都不能成功了。於是又看了看上面的一段話。
第二句:區域的原點在左上方(後面才知道坑苦我了!),然後區域是相對於設備的大小的,默認值是CGRectMake(0, 0, 1, 1),這時候我才知道是有比例關系的,最大值才是1,也就是說只要除以相應的設備寬和高的大小不就行了?然後就改成

[_outputsetRectOfInterest:CGRectMake(((ScreenWidth-220)/2)/ScreenWidth,(60+64)/ScreenHigh,220/ScreenWidth,220/ScreenHigh)];


按說這樣應該就完美了,但是才知道我還是高興得太早了,一掃描才發現完全不是那麼回事,差很多。

於是我就一點一點調,但是最後也沒調成功,最後一狠心有設置了一個很確定的值。

[_output setRectOfInterest:CGRectMake(0.5,0.5,0.5, 0.5)];


這次應該很確定是在右下方的四分之一區域吧,嘿嘿。

但是事實又一次打擊了我,掃描後發現是左下的四分之一區域,也就是說rectOfInterest的原點是右上角!!!

回頭又一想,即使右上角是原點那也應該沒有影響啊,但是為什麼不行呢,不會是原點的 X 和 Y 互換了吧?算了不管怎麼著,試一試吧。

[_outputsetRectOfInterest:CGRectMake((60+64)/ScreenHigh,((ScreenWidth-220)/2)/ScreenWidth,220/ScreenWidth,220/ScreenHigh)];


又掃描了一下發現成功了!果然原點正確了,我只想說TMD!

但是寬和高又怎麼對不上了?不會也互換了吧!趕緊試試

[_outputsetRectOfInterest:CGRectMake((124)/ScreenHigh,((ScreenWidth-220)/2)/ScreenWidth,220/ScreenHigh,220/ScreenWidth)];

懷著忐忑的心情又試了試,完美掃描!OMG我想死的心都有了。

於是用系統原生的掃描二維碼就完美了!


今天就跟大家分享這一個點,轉載請注明出處,謝謝 — — LC



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