iOS 二維碼和條形碼掃描,獲取焦點(diǎn)及焦距拉近縮放

? ? ? 對于現(xiàn)在的App應(yīng)用來說,掃描二維碼和條形碼這個(gè)功能是再正常不過的一個(gè)功能了,在早期開發(fā)這些功能的時(shí)候,大家或多或少的都接觸過ZXing和ZBar這類的第三方庫疹蛉,但從iOS7以后,蘋果就給我們提供了系統(tǒng)原生的API來支持我們掃描獲取二維碼力麸,ZXing和ZBar在使用中或多或少有不盡如人意的地方可款,再之停止更新很久了,所以今天我們就來聊聊如何用系統(tǒng)原生的方法掃描獲取二維碼末盔,強(qiáng)大的AVFoundation框架給我們提供了掃描私有方法和代理方法。

? ? ?首先獲取流媒體信息我們需要AVCaptureSession對象來管理輸入流和輸出流座慰,AVCaptureVideoPreviewLayer對象來顯示信息陨舱,基本流程如下圖所示

??

AVCaptureSession管理輸入(AVCaptureInput)和輸出(AVCaptureOutput)流,包含開啟和停止會(huì)話方法版仔。

AVCaptureDeviceInput是AVCaptureInput的子類,可以作為輸入捕獲會(huì)話癣朗,用AVCaptureDevice實(shí)例初始化。

AVCaptureDevice代表了物理捕獲設(shè)備如:攝像機(jī)浅浮。用于配置等底層硬件設(shè)置相機(jī)的自動(dòng)對焦模式独榴。

AVCaptureMetadataOutput是AVCaptureOutput的子類,處理輸出捕獲會(huì)話兰珍。捕獲的對象傳遞給一個(gè)委托實(shí)現(xiàn)AVCaptureMetadataOutputObjectsDelegate協(xié)議。協(xié)議方法在指定的派發(fā)隊(duì)列(dispatch queue)上執(zhí)行。

AVCaptureVideoPreviewLayerCALayer的一個(gè)子類欣范,顯示捕獲到的相機(jī)輸出流。

好了看下實(shí)現(xiàn)過程:

添加代理 <AVCaptureMetadataOutputObjectsDelegate>

/** 設(shè)備 */

@property (nonatomic, strong) AVCaptureDevice * device;

/** 輸入輸出的中間橋梁 */

@property (nonatomic, strong) AVCaptureSession * session;

/** 相機(jī)圖層 */

@property (nonatomic, strong) AVCaptureVideoPreviewLayer * previewLayer;

/** 掃描支持的編碼格式的數(shù)組 */

@property (nonatomic, strong) NSMutableArray * metadataObjectTypes;

/** 遮罩層 */

@property (nonatomic, strong) ZFMaskView * maskView;

@property(nonatomic,strong) AVCaptureMetadataOutput * metadataOutput ;//輸出流

@property(nonatomic,strong)AVCaptureDeviceInput * input;//創(chuàng)建輸入流

這里介紹下掃描支持的編碼格式

/*

//設(shè)置支持的掃描類型

由于本項(xiàng)目只支持條形碼掃描令哟,故先屏蔽掉二維碼掃描功能

AVMetadataObjectTypeQRCode,AVMetadataObjectTypeAztecCode,

*/

- (NSMutableArray *)metadataObjectTypes{

if (!_metadataObjectTypes) {

_metadataObjectTypes = [NSMutableArray arrayWithObjects:AVMetadataObjectTypeCode128Code, AVMetadataObjectTypeCode39Code, AVMetadataObjectTypeCode39Mod43Code, AVMetadataObjectTypeCode93Code, AVMetadataObjectTypeEAN13Code, AVMetadataObjectTypeEAN8Code, ?/ ?/我國商品碼主要就是這和 EAN8

AVMetadataObjectTypePDF417Code, AVMetadataObjectTypeUPCECode, nil];

// >= iOS 8

if (floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_7_1) {

[_metadataObjectTypes addObjectsFromArray:@[AVMetadataObjectTypeInterleaved2of5Code, AVMetadataObjectTypeITF14Code, AVMetadataObjectTypeDataMatrixCode]];

}

}

? ? return _metadataObjectTypes;

}

/**

*? 掃描初始化

*/

- (void)capture{

//獲取攝像設(shè)備

self.device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];

//創(chuàng)建輸入流

AVCaptureDeviceInput * input = [AVCaptureDeviceInput deviceInputWithDevice:self.device error:nil];

//創(chuàng)建輸出流

_metadataOutput = [[AVCaptureMetadataOutput alloc] init];

//設(shè)置代理 在主線程里刷新

[_metadataOutput setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];

//初始化鏈接對象

self.session = [[AVCaptureSession alloc] init];

//高質(zhì)量采集率

self.session.sessionPreset = AVCaptureSessionPresetHigh;

[self.session addInput:input];

[self.session addOutput:_metadataOutput];

self.previewLayer = [AVCaptureVideoPreviewLayer layerWithSession:self.session];

self.previewLayer.frame = CGRectMake(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);

self.previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;

self.previewLayer.backgroundColor = [UIColor yellowColor].CGColor;

[self.view.layer addSublayer:self.previewLayer];

//設(shè)置掃描支持的編碼格式(如下設(shè)置條形碼和二維碼兼容)

_metadataOutput.metadataObjectTypes = self.metadataObjectTypes;

//開始捕獲

[self.session startRunning];

}

下一步恼琼,獲取掃描結(jié)果

#pragma mark - AVCaptureMetadataOutputObjectsDelegate-(void)captureOutput:(AVCaptureOutput*)captureOutput didOutputMetadataObjects:(NSArray*)metadataObjects fromConnection:(AVCaptureConnection*)connection

{if(metadataObjects.count>0) {? ? ?

? ?[self.session stopRunning];

?AVMetadataMachineReadableCodeObject*metadataObject = ?metadataObjects[0];

?NSLog(@"%@",metadataObject.stringValue);?

? }}

小結(jié)一下:

如果你的項(xiàng)目只需要掃描二維碼,不考慮條形碼屏富,metadataObjectTypes只需要AVMetadataObjectTypeQRCode就夠了晴竞,反之把這個(gè)去掉


? 下面我主要講講怎么把鏡頭拉近,提高掃描效果狠半,你之前在界面中添加一個(gè)按鈕噩死,添加事件。

#pragma mark - ?焦距

- (void)CameraScaleAction:(UIButton *)sender{

kCameraScale+=0.5; ? //去定義一個(gè)float類型神年,默認(rèn)值為1.0

if(kCameraScale>2.5)

kCameraScale=1.0;

//改變焦距 ? 記住這里的輸出鏈接類型要選中這個(gè)類型已维,否則屏幕會(huì)花的

AVCaptureConnection *connect=[_metadataOutput connectionWithMediaType:AVMediaTypeVideo];

[CATransaction begin];

[CATransaction setAnimationDuration:0.2];

[sender setTitle:[NSString stringWithFormat:@"%.1fX",(float)kCameraScale] forState:UIControlStateNormal];

//主要是改變相機(jī)圖層的大小

[_previewLayer setAffineTransform:CGAffineTransformMakeScale(kCameraScale, kCameraScale)];

connect.videoScaleAndCropFactor= kCameraScale;

[CATransaction commit];

//超出的部分切掉,否則影響掃描效果

self.view.clipsToBounds=YES;

self.view.layer.masksToBounds=YES;

}



這是對比圖,

如果想獲取焦點(diǎn)需要給view添加一個(gè)手勢

////對焦

-(void)foucus:(UITapGestureRecognizer *)sender

{

if(_input.device.position==AVCaptureDevicePositionFront)

return;

if(sender.state==UIGestureRecognizerStateRecognized)

{

CGPoint location=[sender locationInView:self.view];

//對焦

__weak typeof(self) weakSelf=self;

[self focusOnPoint:location completionHandler:^{

weakSelf.focalReticule.center=location;

weakSelf.focalReticule.alpha=0.0;

weakSelf.focalReticule.hidden=NO;

[UIView animateWithDuration:0.3 animations:^{

weakSelf.focalReticule.alpha=1.0;

}completion:^(BOOL finished) {

[UIView animateWithDuration:0.3 animations:^{

weakSelf.focalReticule.alpha=0.0;

}];

}];

}];

}

}

////對某一點(diǎn)對焦

-(void)focusOnPoint:(CGPoint)point completionHandler:(void(^)())completionHandler{

AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];;

CGPoint pointOfInterest = CGPointZero;

CGSize frameSize = self.view.bounds.size;

pointOfInterest = CGPointMake(point.y / frameSize.height, 1.f - (point.x / frameSize.width));

if ([device isFocusPointOfInterestSupported] && [device isFocusModeSupported:AVCaptureFocusModeAutoFocus])

{

NSError *error;

if ([device lockForConfiguration:&error])

{

if ([device isWhiteBalanceModeSupported:AVCaptureWhiteBalanceModeAutoWhiteBalance])

{

[device setWhiteBalanceMode:AVCaptureWhiteBalanceModeAutoWhiteBalance];

}

if ([device isFocusModeSupported:AVCaptureFocusModeContinuousAutoFocus])

{

[device setFocusMode:AVCaptureFocusModeAutoFocus];

[device setFocusPointOfInterest:pointOfInterest];

}

if([device isExposurePointOfInterestSupported] && [device isExposureModeSupported:AVCaptureExposureModeContinuousAutoExposure])

{

[device setExposurePointOfInterest:pointOfInterest];

[device setExposureMode:AVCaptureExposureModeContinuousAutoExposure];

}

[device unlockForConfiguration];

if(completionHandler)

completionHandler();

}

}

else{

if(completionHandler)

completionHandler();

}

} ? ? ? ? ? ? ? ??

好了瘤袖,歡迎大家指正

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末衣摩,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子捂敌,更是在濱河造成了極大的恐慌艾扮,老刑警劉巖,帶你破解...
    沈念sama閱讀 207,248評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件占婉,死亡現(xiàn)場離奇詭異泡嘴,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)逆济,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,681評論 2 381
  • 文/潘曉璐 我一進(jìn)店門酌予,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人奖慌,你說我怎么就攤上這事抛虫。” “怎么了简僧?”我有些...
    開封第一講書人閱讀 153,443評論 0 344
  • 文/不壞的土叔 我叫張陵建椰,是天一觀的道長。 經(jīng)常有香客問我岛马,道長棉姐,這世上最難降的妖魔是什么屠列? 我笑而不...
    開封第一講書人閱讀 55,475評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮伞矩,結(jié)果婚禮上笛洛,老公的妹妹穿的比我還像新娘。我一直安慰自己乃坤,他們只是感情好苛让,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,458評論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著侥袜,像睡著了一般蝌诡。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上枫吧,一...
    開封第一講書人閱讀 49,185評論 1 284
  • 那天浦旱,我揣著相機(jī)與錄音,去河邊找鬼九杂。 笑死颁湖,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的例隆。 我是一名探鬼主播甥捺,決...
    沈念sama閱讀 38,451評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼镀层!你這毒婦竟也來了镰禾?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,112評論 0 261
  • 序言:老撾萬榮一對情侶失蹤唱逢,失蹤者是張志新(化名)和其女友劉穎吴侦,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體坞古,經(jīng)...
    沈念sama閱讀 43,609評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡备韧,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,083評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了痪枫。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片织堂。...
    茶點(diǎn)故事閱讀 38,163評論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖奶陈,靈堂內(nèi)的尸體忽然破棺而出易阳,到底是詐尸還是另有隱情,我是刑警寧澤吃粒,帶...
    沈念sama閱讀 33,803評論 4 323
  • 正文 年R本政府宣布潦俺,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏黑竞。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,357評論 3 307
  • 文/蒙蒙 一疏旨、第九天 我趴在偏房一處隱蔽的房頂上張望很魂。 院中可真熱鬧,春花似錦檐涝、人聲如沸遏匆。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,357評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽幅聘。三九已至,卻和暖如春窃植,著一層夾襖步出監(jiān)牢的瞬間帝蒿,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,590評論 1 261
  • 我被黑心中介騙來泰國打工巷怜, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留葛超,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,636評論 2 355
  • 正文 我出身青樓延塑,卻偏偏與公主長得像绣张,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子关带,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,925評論 2 344

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