iOS開發之二維碼

1、為什么使用二維碼?

在手機客戶端應用里,對二維碼的使用也比較多。常見的功能有物品信息查詢,登錄信息驗證,掃描登錄,掃描支付等。但是為什么使用它呢?

*二維碼包含更多的信息量

*二維碼采用了高密度編碼

*編碼范圍廣。二維碼可以把圖片、聲音、文字、簽字、指紋等可以數字化的信息進行編碼,用條碼表示出來;可以表示多種語言文字;可表示圖像數據

*二維碼譯碼準確。我們知道二維碼只是一個圖形,想要獲取圖形中的內容就需要對圖形進行譯碼。二維碼的譯碼誤碼率為千萬分之一,而普通條形碼的譯碼誤碼率的百分之二要低很多。

*安全。能夠引入加密措施,與條形碼相比,二維碼的保密性更好。通過在二維碼中引入加密措施,更好的保護譯碼內容不被他人獲得。

因為二維碼的這些特點,在項目里用到它的地方也會比較多。

2、怎么生成二維碼?

導入CoreImage框架,通過濾鏡CIFilter生成二維碼

二維碼的內容(傳統的條形碼只能放數字):純文本,名片,URL


// 1. 實例化二維碼濾鏡

CIFilter *filter = [CIFilter filterWithName:@"CIQRCodeGenerator"];

// 2. 恢復濾鏡的默認屬性

[filter setDefaults];

// 3. 將字符串轉換成

NSData NSData *data = [str dataUsingEncoding:NSUTF8StringEncoding];

// 4. 通過KVO設置濾鏡inputMessage數據

[filter setValue:data forKey:@"inputMessage"];

// 5. 獲得濾鏡輸出的圖像

CIImage *outputImage = [filter outputImage];

// 6. 將CIImage轉換成UIImage,并放大顯示

return [UIImage imageWithCIImage:outputImage scale:20.0 orientation:UIImageOrientationUp];

3、掃描二維碼

掃描二維碼就要用到系統設備,攝像頭。這就要導入AVFoundation類庫,并遵守AVCaptureMetadataOutputObjectsDelegate協議

這里會用到 AVCaptureDevice? 捕捉用的設備、AVCaptureDeviceInput 輸入通道、AVCaptureSession 對采集到的信息的處理與傳輸、AVCaptureMetadataOutput輸出通道這幾個的對象屬性,當然還需要一張預覽視圖,為了顯示正在進行掃描,還會添加動畫效果。就是我們常見的一個上下刷動的網格線或者亮度條,其實它與采集信息無關。

#import "QRCodeVC.h"

#import <AVFoundation/AVFoundation.h>

@interface QRCodeVC ( )<AVCaptureMetadataOutputObjectsDelegate>

@property (nonatomic, strong) AVCaptureDevice *device;//撲捉用的設備

@property (nonatomic, strong) AVCaptureSession *session;//采集到的信息的處理與傳輸

@property (nonatomic, strong) AVCaptureMetadataOutput *output;//輸出通道

@property (nonatomic, strong)UIView *preview;//預覽視圖

@property (nonatomic, strong)UIImageView *inamationView;//動畫View

@property (nonatomic, strong) NSTimer *timer;//刷新動畫的View

@end

接下來就是對掃描界面的搭建和程序處理,代碼符上如下:

@implementation QRCodeVC

- (void)viewDidLoad {

? ? [super viewDidLoad];

? ? [self innationQRCode];

? ? //設置UI效果

? ? //添加矩形邊框

? ? UIImage *image = [UIImage imageNamed:@"qrcode_border"];

? ? //拉伸矩形

? ? image = [image resizableImageWithCapInsets:UIEdgeInsetsMake(25, 25, 26, 26)];

? ? UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, [[UIScreen mainScreen] bounds].size.width - 80, [[UIScreen mainScreen] bounds].size.width - 80)];

? ? [imageView setImage:image];

? ? CGPoint point = self.view.center;

? ? point.y += -50;

? ? imageView.center = point;

? ? [self.view addSubview:imageView];

? ? //剪切掉超出區域的動畫

? ? imageView.clipsToBounds = YES;

? ? //動畫效果

? ? UIImageView *anamiView = [[UIImageView alloc] initWithFrame:imageView.bounds];

? ? anamiView.image = [UIImage imageNamed:@"qrcode_scanline_qrcode"];

? ? [imageView addSubview:anamiView];

? ? self.inamationView = anamiView;

? ? self.timer = [NSTimer scheduledTimerWithTimeInterval:0.01f target:self selector:@selector(changeInamation) userInfo:nil repeats:YES];

}

-(void)changeInamation{

? ? //改變動畫

? ? self.inamationView.frame = CGRectOffset(self.inamationView.frame, 0, 2);

? ? if (self.inamationView.frame.origin.y >= self.inamationView.frame.size.height) {

? ? ? ? self.inamationView.frame = CGRectOffset(self.inamationView.bounds, 0, -self.inamationView.frame.size.height);

? ? }

}

-(void)viewDidAppear:(BOOL)animated{

? ? [super viewDidAppear:animated];

? ? //開啟二維碼掃描,撲捉信息

? ? [self start];

}

-(void)viewWillDisappear:(BOOL)animated{

? ? [super viewWillDisappear:animated];

? ? //停止二維碼掃描

? ? [self end];

}

//初始化配置

-(void)innationQRCode{

? ? //獲取設備

? ? self.device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];

? ? //生成Input

? ? NSError *error;

? ? self.input = [AVCaptureDeviceInput deviceInputWithDevice:self.device error:&error];

? ? if (error) {

? ? ? ? NSLog(@"%@", error);

? ? ? ? return;

? ? }

? ? //初始化session并且把input添加到session

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

? ? if ([self.session canAddInput:self.input]) {

? ? ? ? [self.session addInput:self.input];

? ? }

? ? //初始化output

? ? AVCaptureMetadataOutput *output = [[AVCaptureMetadataOutput alloc] init];

? ? //設置?delegate

? ? dispatch_queue_t queue;

? ? queue = dispatch_queue_create("muQueue", NULL);//串行隊列

? ? [output setMetadataObjectsDelegate:self queue:queue];

? ? self.output = output;

? ? //把output添加到session中

? ? [self.session addOutput:self.output];

? ? //配置輸出的數據類型,支持所有的數據類型

? ? [self.output setMetadataObjectTypes:self.output.availableMetadataObjectTypes];

? ? //設置預覽圖層,將session中撲捉的畫面預覽

? ? AVCaptureVideoPreviewLayer *videoLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:self.session];

? ? [videoLayer setVideoGravity:AVLayerVideoGravityResizeAspectFill];

? ? [videoLayer setFrame:self.view.frame];

? ? //初始化預覽視圖

? ? self.preview = [[UIView alloc] initWithFrame:self.view.bounds];

? ? [self.view addSubview:self.preview];

? ? [self.preview.layer addSublayer:videoLayer];

}

- (IBAction)cancel:(id)sender { ? ?//取消掃描

? ? [self dismissViewControllerAnimated:YES completion:nil];

}

-(void)start{ ??

? ? [self.session startRunning];

? ? [self.timer fire];

}

-(void)end{

? ? [self.session stopRunning];

? ? [self.timer invalidate];

}

-(void)result:(NSString *)str{

? ? //得到結果,停止掃描,如果是網頁,打開網頁,如果是字符串,展示字符串

? ? [self.session stopRunning];

? ? UIViewController *vc = [self.storyboard instantiateViewControllerWithIdentifier:@"resultVC"];

? ? [vc setValue:str forKey:@"result"];

? ? if (self.navigationController.viewControllers.count > 1) {

? ? ? ? return;

? ? }

? ? [self.navigationController pushViewController:vc animated:YES];

}

#pragma avcapture

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

? ? id object = metadataObjects.firstObject;

? ? //只關心機器識別碼

? ? if ([object isKindOfClass:[AVMetadataMachineReadableCodeObject class]]) {

? ? ? ? AVMetadataMachineReadableCodeObject *obj = (AVMetadataMachineReadableCodeObject *)object;

? ? ? ? NSLog(@"%@", obj);

? ? ? ? [self performSelectorOnMainThread:@selector(result:) withObject:obj.stringValue waitUntilDone:NO];

? ? }

}

@end

若有錯誤,歡迎大家指出。有好的方式或代碼,歡迎大家給我留言,吾將感激涕零,哈哈。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容