iOS 采用原生AVFoundation框架實(shí)現(xiàn)二維碼掃描功能

將要用到的知識(shí)點(diǎn):AVFoundation 框架策菜,CAGradientLayer ,CAShapeLayer,UIBezierPath;

效果圖

89897.gif

1.聲明(建立一個(gè)ScanCode : UIView類)

.m文件

#import "ScanCode.h"
#import <AVFoundation/AVFoundation.h>
#define SelfW self.bounds.size.width
#define SelfH self.bounds.size.height
#define ScanLineH 30
@interface ScanCode ()<AVCaptureMetadataOutputObjectsDelegate> // 用于處理采集信息的代理
{
    AVCaptureSession *session; // 輸入輸出的中間橋梁
    
    CAGradientLayer *scanLayer;
    
    UIView *scanBox;
}

@end

2.實(shí)現(xiàn)代碼

@implementation ScanCode


- (instancetype)initWithFrame:(CGRect)frame
{
    if (self = [super initWithFrame:frame]) {
        // 獲取攝像設(shè)備
        AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
        // 創(chuàng)建輸入流
        AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:device error:nil];
        
        // 創(chuàng)建輸出流
        AVCaptureMetadataOutput *output = [[AVCaptureMetadataOutput alloc]init];
        
        // 設(shè)置代理垃喊,在主線程里刷新
        [output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
        
        // 初始化鏈接對(duì)象
        session = [[AVCaptureSession alloc]init];
        
        // 高質(zhì)量采集率
        [session setSessionPreset:AVCaptureSessionPresetHigh];
        
        [session addInput:input];
        [session addOutput:output];
        
        
        // 設(shè)置掃碼支持的編碼格式(如下設(shè)置條形碼和二維碼兼容)
        output.metadataObjectTypes = @[AVMetadataObjectTypeQRCode,AVMetadataObjectTypeEAN13Code,AVMetadataObjectTypeEAN8Code,AVMetadataObjectTypeCode128Code];
        
        // 實(shí)例化預(yù)覽圖層
        AVCaptureVideoPreviewLayer *layer = [AVCaptureVideoPreviewLayer layerWithSession:session];
        // 設(shè)置預(yù)覽圖層填充方式
        layer.videoGravity = AVLayerVideoGravityResizeAspectFill;
        layer.frame = self.layer.bounds;
        [self.layer insertSublayer:layer atIndex:0];
        UIView *maskView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, SelfW,SelfH)];
        
        [maskView setBackgroundColor:[UIColor colorWithWhite:0 alpha:0.7]];
        [self addSubview:maskView];
       
        
        // 運(yùn)用貝塞爾曲線配合CAShapeLayer

        UIBezierPath *path = [UIBezierPath bezierPathWithRect:CGRectMake(0, 0, SelfW, SelfH)];
        
        // MARK: circlePath 畫(huà)圓
        // [path appendPath:[UIBezierPath bezierPathWithArcCenter:CGPointMake(SelfW / 2, 200) radius:100 startAngle:0 endAngle:2*M_PI clockwise:NO]];
        
        // MARK: roundRectanglePath 畫(huà)矩形!
         [path appendPath:[[UIBezierPath bezierPathWithRoundedRect:CGRectMake(SelfW *0.2f, SelfH*0.35f, SelfW - SelfW*0.4f, SelfH - SelfH *0.7f) cornerRadius:0] bezierPathByReversingPath]];
        
        
        CAShapeLayer *shapeLayer = [CAShapeLayer layer];
        
        shapeLayer.path = path.CGPath;
        
        [maskView.layer setMask:shapeLayer];
        
        //[self setBackgroundColor:[UIColor colorWithWhite:0 alpha:0.7]];
        // 設(shè)置掃描范圍
        // 注意袜炕,這個(gè)屬性各個(gè)方向的取值范圍為0-1本谜,表示占layer層的長(zhǎng)度比例,x對(duì)應(yīng)的是距離左上角的垂直距離偎窘,y對(duì)應(yīng)的是距離左上角的水平距離乌助,w對(duì)應(yīng)的是底部距離左上角的垂直距離溜在,h對(duì)應(yīng)的是最右邊距離左上角的水平距離
        output.rectOfInterest = CGRectMake(0.35f, 0.2f, 0.7f, 0.8f);
        
        // 設(shè)置掃描框
        scanBox = [[UIView alloc]initWithFrame:CGRectMake(SelfW *0.2f, SelfH*0.35f, SelfW - SelfW*0.4f, SelfH - SelfH *0.7f)];
        
        scanBox.layer.borderColor = [UIColor greenColor].CGColor;
        scanBox.layer.borderWidth = 1.0f;
        [self addSubview:scanBox];
        
        
        // 掃描線
        scanLayer = [[CAGradientLayer alloc]init];
        scanLayer.frame = CGRectMake(0, 0, scanBox.bounds.size.width, ScanLineH);
        [scanBox.layer addSublayer:scanLayer];
        // 設(shè)置漸變顏色方向
        scanLayer.startPoint = CGPointMake(0, 0);
        scanLayer.endPoint = CGPointMake(0, 1);
        // 設(shè)定顏色組
        scanLayer.colors = @[(__bridge id)[UIColor clearColor].CGColor,(__bridge id)[UIColor brownColor].CGColor];
        
        NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:0.1f target:self selector:@selector(moveScanLayer:) userInfo:nil repeats:YES];
        [timer fire];
        // 開(kāi)始捕獲
        [session startRunning];

    }
    
    
    return self;
}

// 以上之后我們的UI上已經(jīng)可以看到攝像頭捕獲的內(nèi)容,只要實(shí)現(xiàn)代理中的方法他托,就可以完成二維碼條形碼的掃描:
-(void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection{
    if (metadataObjects.count>0) {
        
        AVMetadataMachineReadableCodeObject * metadataObject = [metadataObjects objectAtIndex : 0 ];
        
        [session stopRunning];
        //輸出掃描字符串
        NSLog(@"%@",metadataObject.stringValue);
        
        [scanLayer removeFromSuperlayer];
        
    }
}

// 實(shí)現(xiàn)計(jì)時(shí)器方法moveScanLayer:

- (void)moveScanLayer:(NSTimer *)timer
{
    CGRect frame = scanLayer.frame;
    if (scanBox.frame.size.height < (scanLayer.frame.origin.y+ScanLineH + 5)) {
        frame.origin.y = -5;
        scanLayer.frame = frame;
    }else{
        frame.origin.y += 5;
        [UIView animateWithDuration:0.1 animations:^{
            scanLayer.frame = frame;
        }];
    }
    
    
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末掖肋,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子赏参,更是在濱河造成了極大的恐慌志笼,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,123評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件把篓,死亡現(xiàn)場(chǎng)離奇詭異纫溃,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)韧掩,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,031評(píng)論 2 384
  • 文/潘曉璐 我一進(jìn)店門紊浩,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人揍很,你說(shuō)我怎么就攤上這事郎楼。” “怎么了窒悔?”我有些...
    開(kāi)封第一講書(shū)人閱讀 156,723評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵呜袁,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我简珠,道長(zhǎng)阶界,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,357評(píng)論 1 283
  • 正文 為了忘掉前任聋庵,我火速辦了婚禮膘融,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘祭玉。我一直安慰自己氧映,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,412評(píng)論 5 384
  • 文/花漫 我一把揭開(kāi)白布脱货。 她就那樣靜靜地躺著岛都,像睡著了一般。 火紅的嫁衣襯著肌膚如雪振峻。 梳的紋絲不亂的頭發(fā)上臼疫,一...
    開(kāi)封第一講書(shū)人閱讀 49,760評(píng)論 1 289
  • 那天,我揣著相機(jī)與錄音扣孟,去河邊找鬼烫堤。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的鸽斟。 我是一名探鬼主播拔创,決...
    沈念sama閱讀 38,904評(píng)論 3 405
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼湾盗!你這毒婦竟也來(lái)了伏蚊?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 37,672評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤格粪,失蹤者是張志新(化名)和其女友劉穎躏吊,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體帐萎,經(jīng)...
    沈念sama閱讀 44,118評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡比伏,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,456評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了疆导。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片赁项。...
    茶點(diǎn)故事閱讀 38,599評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖澈段,靈堂內(nèi)的尸體忽然破棺而出悠菜,到底是詐尸還是另有隱情,我是刑警寧澤败富,帶...
    沈念sama閱讀 34,264評(píng)論 4 328
  • 正文 年R本政府宣布悔醋,位于F島的核電站,受9級(jí)特大地震影響兽叮,放射性物質(zhì)發(fā)生泄漏芬骄。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,857評(píng)論 3 312
  • 文/蒙蒙 一鹦聪、第九天 我趴在偏房一處隱蔽的房頂上張望账阻。 院中可真熱鬧,春花似錦泽本、人聲如沸淘太。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,731評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)蒲牧。三九已至,卻和暖如春嘁捷,著一層夾襖步出監(jiān)牢的瞬間造成,已是汗流浹背显熏。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,956評(píng)論 1 264
  • 我被黑心中介騙來(lái)泰國(guó)打工雄嚣, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,286評(píng)論 2 360
  • 正文 我出身青樓缓升,卻偏偏與公主長(zhǎng)得像鼓鲁,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子港谊,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,465評(píng)論 2 348

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

  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫(kù)骇吭、插件、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 12,059評(píng)論 4 62
  • 夏憶成殤,往事已矣 是誰(shuí)點(diǎn)綴于我眼眸 你若繁花似錦 相襯斜陽(yáng) 牽絆我滿心歡喜 是誰(shuí)淺笑于我耳畔 聞風(fēng)輕撫發(fā)絲 驀然...
    雨箬顏閱讀 203評(píng)論 0 4
  • 初看到這本書(shū)斜筐,裝幀設(shè)計(jì)很簡(jiǎn)單龙致,但紫色框里的“相助”二字卻在一瞬間抵達(dá)心靈∏炅矗“The Help”的字眼在預(yù)示著某種即...
    099a6727fdb1閱讀 241評(píng)論 0 1
  • 我自己的經(jīng)歷告訴我:哪怕慢一點(diǎn)也一定不要放棄嗤练,做事情做到一半是沒(méi)有價(jià)值的榛了,任何能做成大事的人,無(wú)不是經(jīng)過(guò)長(zhǎng)年累月的...
    小公主1111閱讀 329評(píng)論 0 0