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

寫這篇文章的主要原因不是展示如何使用 AVFoundation 來進(jìn)行二維碼掃描搓蚪,更主要的是限制掃描二維碼的范圍惨好。(因?yàn)槟J(rèn)的是全屏掃描)


項(xiàng)目遇到掃描二維碼的功能需求,這里我放棄了使用三方庫,而采用了蘋果原生的掃描谅摄。
原生的好處就是掃描特別快效率特別高法精,但是遇到一個(gè)問題就是不知道怎么去限制掃描范圍多律。

還是先簡單說一下怎么使用來進(jìn)行二維碼掃描吧痴突。
首先是要用到的幾個(gè)類

@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;

他們之間的關(guān)系可以看下面的篇文章
傳送門

下面分別創(chuàng)建他們

// 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];

 然后實(shí)現(xiàn) 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;        
}

}

到此為止就可以成功掃描二維碼了,但是有個(gè)尷尬的問題狼荞,這時(shí)的掃描是全屏掃描的辽装。即


Screenshot_2016-08-26-13-47-34_com.tencent.mm.png

一般情況下項(xiàng)目中的掃描頁面是這樣的,但是當(dāng)你掃描的時(shí)候會發(fā)現(xiàn)在二維碼還沒進(jìn)入中心的那個(gè)小方塊時(shí)相味,就已經(jīng)成功掃描完成了拾积,這對于體驗(yàn)來說很不好。但是由于那時(shí)候趕項(xiàng)目就沒有時(shí)間優(yōu)化丰涉。終于今天抽出來時(shí)間了拓巧。
我從早上上班開始一直搞到下午,把所有想到的方法都試了一遍一死,但是都不行(都是淚)肛度,最后將要放棄的時(shí)候發(fā)現(xiàn)了一個(gè)比較可疑的點(diǎn)。

@property(nonatomic)CGRect rectOfInterest NS_AVAILABLE_IOS(7_0);

這是的 AVCaptureMetadataOutput 一個(gè)屬性投慈,它的解釋是
@discussion
The value of this property is a CGRect that determines the receiver'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.

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

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

//中間區(qū)域的寬和高都是220 ScreenWidth為設(shè)備屏幕寬度
但是卻發(fā)現(xiàn)怎么掃描都不能成功了伪煤。于是又看了看上面的一段話加袋。

第二句:區(qū)域的原點(diǎn)在左上方(后面才知道坑苦我了!)抱既,然后區(qū)域是相對于設(shè)備的大小的职烧,默認(rèn)值是CGRectMake(0, 0, 1, 1),這時(shí)候我才知道是有比例關(guān)系的蝙砌,最大值才是1阳堕,也就是說只要除以相應(yīng)的設(shè)備寬和高的大小不就行了?然后就改成

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

按說這樣應(yīng)該就完美了择克,但是才知道我還是高興得太早了恬总,一掃描才發(fā)現(xiàn)完全不是那么回事,差很多肚邢。
于是我就一點(diǎn)一點(diǎn)調(diào)壹堰,但是最后也沒調(diào)成功,最后一狠心有設(shè)置了一個(gè)很確定的值骡湖。

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

這次應(yīng)該很確定是在右下方的四分之一區(qū)域吧贱纠,嘿嘿。
但是事實(shí)又一次打擊了我响蕴,掃描后發(fā)現(xiàn)是左下的四分之一區(qū)域谆焊,也就是說rectOfInterest的原點(diǎn)是右上角!F忠摹辖试!
回頭又一想辜王,即使右上角是原點(diǎn)那也應(yīng)該沒有影響啊,但是為什么不行呢罐孝,不會是原點(diǎn)的 X 和 Y 互換了吧呐馆?算了不管怎么著,試一試吧莲兢。

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

又掃描了一下發(fā)現(xiàn)成功了汹来!果然原點(diǎn)正確了,我只想說TMD改艇!
但是寬和高又怎么對不上了收班?不會也互換了吧!趕緊試試

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

懷著忐忑的心情又試了試遣耍,完美掃描闺阱!OMG我想死的心都有了炮车。
于是用系統(tǒng)原生的掃描二維碼就完美了舵变!

原文

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市瘦穆,隨后出現(xiàn)的幾起案子纪隙,更是在濱河造成了極大的恐慌,老刑警劉巖扛或,帶你破解...
    沈念sama閱讀 221,198評論 6 514
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件绵咱,死亡現(xiàn)場離奇詭異,居然都是意外死亡熙兔,警方通過查閱死者的電腦和手機(jī)悲伶,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,334評論 3 398
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來住涉,“玉大人麸锉,你說我怎么就攤上這事∮呱” “怎么了花沉?”我有些...
    開封第一講書人閱讀 167,643評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長媳握。 經(jīng)常有香客問我碱屁,道長,這世上最難降的妖魔是什么蛾找? 我笑而不...
    開封第一講書人閱讀 59,495評論 1 296
  • 正文 為了忘掉前任娩脾,我火速辦了婚禮,結(jié)果婚禮上打毛,老公的妹妹穿的比我還像新娘柿赊。我一直安慰自己架曹,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,502評論 6 397
  • 文/花漫 我一把揭開白布闹瞧。 她就那樣靜靜地躺著绑雄,像睡著了一般。 火紅的嫁衣襯著肌膚如雪奥邮。 梳的紋絲不亂的頭發(fā)上万牺,一...
    開封第一講書人閱讀 52,156評論 1 308
  • 那天,我揣著相機(jī)與錄音洽腺,去河邊找鬼脚粟。 笑死,一個(gè)胖子當(dāng)著我的面吹牛蘸朋,可吹牛的內(nèi)容都是我干的核无。 我是一名探鬼主播,決...
    沈念sama閱讀 40,743評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼藕坯,長吁一口氣:“原來是場噩夢啊……” “哼团南!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起炼彪,我...
    開封第一講書人閱讀 39,659評論 0 276
  • 序言:老撾萬榮一對情侶失蹤吐根,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后辐马,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體拷橘,經(jīng)...
    沈念sama閱讀 46,200評論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,282評論 3 340
  • 正文 我和宋清朗相戀三年喜爷,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了冗疮。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,424評論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡檩帐,死狀恐怖术幔,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情轿塔,我是刑警寧澤特愿,帶...
    沈念sama閱讀 36,107評論 5 349
  • 正文 年R本政府宣布,位于F島的核電站勾缭,受9級特大地震影響揍障,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜俩由,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,789評論 3 333
  • 文/蒙蒙 一毒嫡、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦兜畸、人聲如沸努释。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,264評論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽伐蒂。三九已至,卻和暖如春肛鹏,著一層夾襖步出監(jiān)牢的瞬間逸邦,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,390評論 1 271
  • 我被黑心中介騙來泰國打工在扰, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留缕减,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,798評論 3 376
  • 正文 我出身青樓芒珠,卻偏偏與公主長得像桥狡,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子皱卓,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,435評論 2 359

推薦閱讀更多精彩內(nèi)容