iOS 二維碼生成及掃碼詳解及實(shí)例代碼
iOS二維碼生成及掃碼
現(xiàn)在越來(lái)越多的應(yīng)用加入二維碼相關(guān)的業(yè)務(wù),在iOS開(kāi)發(fā)市場(chǎng)上很多開(kāi)發(fā)人員都在使用第三方的掃碼與生成二維碼的控件,個(gè)人認(rèn)為此類(lèi)的第三方控件識(shí)別度不高。最近正好整理新框架的事情,研究了一下。具體代碼如下
生成二維碼代碼
/**
* @author 半 飽, 15-12-18
*
* @brief 生成二維碼圖片
*
* @param code 生成二維碼圖片內(nèi)容
* @param width 二維碼圖片寬度
* @param height 二維碼圖片高度
*
* @return 返回UIImage對(duì)象
*/
- (UIImage *)generateQRCode:(NSString *)code width:(CGFloat)width height:(CGFloat)height {
CIImage *qrcodeImage;
NSData *data = [code dataUsingEncoding:NSISOLatin1StringEncoding allowLossyConversion:false];
CIFilter *filter = [CIFilter filterWithName:@"CIQRCodeGenerator"];
[filter setValue:data forKey:@"inputMessage"];
[filter setValue:@"H" forKey:@"inputCorrectionLevel"];
qrcodeImage = [filter outputImage];
CGFloat scaleX = width / qrcodeImage.extent.size.width;
CGFloat scaleY = height / qrcodeImage.extent.size.height;
CIImage *transformedImage = [qrcodeImage imageByApplyingTransform:CGAffineTransformScale(CGAffineTransformIdentity, scaleX, scaleY)];
return [UIImage imageWithCIImage:transformedImage];
}
掃描二維碼代碼
#import <AVFoundation/AVFoundation.h>
static const float lightWidth = 240.f;
static const float lightHeight = 240.f;
static const float crossLineWidth = 2.f;
static const float crossLineHeight = 15.f;
@interface BBScanCodeViewController ()<AVCaptureMetadataOutputObjectsDelegate> {
float leftWith;
float topHeight;
}
@property (strong , nonatomic ) AVCaptureDevice *captureDevice;
@property (strong , nonatomic ) AVCaptureDeviceInput *captureInput;
@property (strong , nonatomic ) AVCaptureMetadataOutput *captureOutput;
@property (strong , nonatomic ) AVCaptureSession *captureSession;
@property (strong , nonatomic ) AVCaptureVideoPreviewLayer *capturePreview;
@property (strong,nonatomic) UIButton *flashLightBtn;
@property (strong,nonatomic) UIImageView *lineImageView;
@end
@implementation BBScanCodeViewController
@synthesize captureDevice = _captureDevice;
@synthesize captureInput = _captureInput;
@synthesize captureOutput = _captureOutput;
@synthesize capturePreview = _capturePreview;
@synthesize captureSession = _captureSession;
@synthesize delegate = _delegate;
@synthesize isRectScan = _isRectScan;
@synthesize lineImageView = _lineImageView;
@synthesize flashLightBtn = _flashLightBtn;
- (void)viewDidLoad {
[super viewDidLoad];
self.isShowNavigationItem = YES;
CGRect screenRect = [UIScreen mainScreen].bounds;
leftWith = (screenRect.size.width - lightWidth) / 2;
topHeight =(screenRect.size.height - lightHeight) / 2;
#if !TARGET_IPHONE_SIMULATOR
[self initScanCode];
#endif
[self initLayer];
[self initViewControl];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(willResignActiveNotification) name:UIApplicationWillResignActiveNotification object:nil]; //監(jiān)聽(tīng)是否觸發(fā)home鍵掛起程序.
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didBecomeActiveNotification) name:UIApplicationDidBecomeActiveNotification object:nil]; //監(jiān)聽(tīng)是否重新進(jìn)入程序程序.
}
-(void)viewWillDisappear:(BOOL)animated {
[self stopScanCode];
[super viewWillDisappear:animated];
}
- (void)willResignActiveNotification {
_flashLightBtn.selected = NO;
}
- (void)didBecomeActiveNotification {
}
//加載界面上的控件,如:加上閃光燈按鈕等
- (void)initViewControl {
@autoreleasepool {
_flashLightBtn = [UIButton buttonWithType:UIButtonTypeCustom];
[_flashLightBtn setImage:[UIImage imageNamed:@"OpenFlashLight.png"] forState:UIControlStateNormal];
[_flashLightBtn setImage:[UIImage imageNamed:@"CloseFlashLight.png"] forState:UIControlStateSelected];
_flashLightBtn.frame = CGRectMake(leftWith, 80.f, 30.f, 30.f);
[_flashLightBtn addTarget:self action:@selector(systemFlashLight) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:_flashLightBtn];
_lineImageView = [[UIImageView alloc] initWithImage:nil];
_lineImageView.backgroundColor = [UIColor greenColor];
_lineImageView.frame = CGRectMake(leftWith, topHeight, lightWidth, 2);
[self.view addSubview:_lineImageView];
[self scanLineAnimation];
}
}
- (void)scanLineAnimation {
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:4.f];
//設(shè)置代理
[UIView setAnimationDelegate:self];
//設(shè)置動(dòng)畫(huà)執(zhí)行完畢調(diào)用的事件
[UIView setAnimationDidStopSelector:@selector(didViewAnimation)];
_lineImageView.frame = CGRectMake(leftWith,topHeight + lightHeight-2,lightWidth,2);
[UIView commitAnimations];
}
-(void)didViewAnimation {
// self.navigationController
_lineImageView.frame = CGRectMake(leftWith, topHeight, lightWidth, 2);
[self scanLineAnimation];
}
- (void)insertLayerWithFrame:(CGRect)frame withBackgroundColor:(UIColor *)backgroundColor {
@autoreleasepool {
CALayer *layer = [CALayer layer];
layer.backgroundColor = backgroundColor.CGColor;
layer.frame = frame;
[self.view.layer addSublayer:layer];
}
}
//初始化layer層,繪制半透明區(qū)域
-(void) initLayer {
//公共參數(shù)
UIColor *fillColor = [UIColor colorWithRed:0xae/255.f green:0xae/255.f blue:0xae/255.f alpha:0.4];
UIColor *crossColor = [UIColor greenColor];
CGRect screenRect = [UIScreen mainScreen].bounds;
[self insertLayerWithFrame:CGRectMake(0, 0, leftWith, screenRect.size.height) withBackgroundColor:fillColor];
[self insertLayerWithFrame:CGRectMake(leftWith, 0, lightWidth, topHeight) withBackgroundColor:fillColor];
[self insertLayerWithFrame:CGRectMake(leftWith + lightWidth, 0, leftWith, screenRect.size.height) withBackgroundColor:fillColor];
[self insertLayerWithFrame:CGRectMake(leftWith, topHeight + lightHeight, lightWidth, topHeight) withBackgroundColor:fillColor];
[self insertLayerWithFrame:CGRectMake(leftWith, topHeight, crossLineWidth, crossLineHeight) withBackgroundColor:crossColor];
[self insertLayerWithFrame:CGRectMake(leftWith, topHeight, crossLineHeight, crossLineWidth) withBackgroundColor:crossColor];
[self insertLayerWithFrame:CGRectMake(leftWith + lightWidth - crossLineHeight, topHeight, crossLineHeight, crossLineWidth) withBackgroundColor:crossColor];
[self insertLayerWithFrame:CGRectMake(leftWith + lightWidth - crossLineWidth, topHeight, crossLineWidth, crossLineHeight) withBackgroundColor:crossColor];
[self insertLayerWithFrame:CGRectMake(leftWith, topHeight + lightHeight - crossLineHeight, crossLineWidth, crossLineHeight) withBackgroundColor:crossColor];
[self insertLayerWithFrame:CGRectMake(leftWith, topHeight + lightHeight - crossLineWidth, crossLineHeight, crossLineWidth) withBackgroundColor:crossColor];
[self insertLayerWithFrame:CGRectMake(leftWith + lightWidth - crossLineHeight, topHeight + lightHeight - crossLineWidth, crossLineHeight, crossLineWidth) withBackgroundColor:crossColor];
[self insertLayerWithFrame:CGRectMake(leftWith + lightWidth - crossLineWidth, topHeight + lightHeight - crossLineHeight, crossLineWidth, crossLineHeight) withBackgroundColor:crossColor];
}
-(void)initScanCode {
@autoreleasepool {
_captureDevice = [ AVCaptureDevice defaultDeviceWithMediaType : AVMediaTypeVideo];
_captureInput = [ AVCaptureDeviceInput deviceInputWithDevice : _captureDevice error : nil ];
_captureOutput = [[ AVCaptureMetadataOutput alloc ] init ];
[_captureOutput setMetadataObjectsDelegate : self queue : dispatch_get_main_queue ()];
if (_isRectScan) {
CGRect screenRect = [UIScreen mainScreen].bounds;
[ _captureOutput setRectOfInterest : CGRectMake (topHeight / screenRect.size.height, leftWith / screenRect.size.width, lightHeight/screenRect.size.height, lightWidth / screenRect.size.width)];
}
_captureSession = [[ AVCaptureSession alloc ] init ];
[_captureSession setSessionPreset : AVCaptureSessionPresetHigh ];
if ([_captureSession canAddInput : _captureInput ])
{
[_captureSession addInput : _captureInput ];
}
if ([_captureSession canAddOutput : _captureOutput ])
{
[_captureSession addOutput : _captureOutput ];
}
_captureOutput.metadataObjectTypes = @[AVMetadataObjectTypeQRCode ] ;
_capturePreview =[ AVCaptureVideoPreviewLayer layerWithSession :_captureSession ];
_capturePreview.videoGravity = AVLayerVideoGravityResizeAspectFill ;
_capturePreview.frame = self.view.layer.bounds ;
[self.view.layer insertSublayer : _capturePreview atIndex : 0 ];
[_captureSession startRunning ];
}
}
- ( void )captureOutput:( AVCaptureOutput *)captureOutput didOutputMetadataObjects:( NSArray *)metadataObjects fromConnection:( AVCaptureConnection *)connection
{
if (metadataObjects != nil && [metadataObjects count] > 0) {
AVMetadataMachineReadableCodeObject *metadataObj = [metadataObjects objectAtIndex:0];
NSString *scanCodeResult;
if ([[metadataObj type] isEqualToString:AVMetadataObjectTypeQRCode]) {
[self stopScanCode];
scanCodeResult = metadataObj.stringValue;
//回調(diào)信息
if (_delegate && [_delegate respondsToSelector:@selector(scanCodeResultByViewController:withScanCodeResult:)]) {
[_delegate scanCodeResultByViewController:self withScanCodeResult:scanCodeResult];
[self.navigationController popViewControllerAnimated:YES];
}
} else {
NSLog(@"掃描信息錯(cuò)誤!");
}
}
}
- (void)systemFlashLight
{
#if !TARGET_IPHONE_SIMULATOR
if([_captureDevice hasTorch] && [self.captureDevice hasFlash])
{
[_captureSession beginConfiguration];
[_captureDevice lockForConfiguration:nil];
if(_captureDevice.torchMode == AVCaptureTorchModeOff)
{
_flashLightBtn.selected = YES;
[_captureDevice setTorchMode:AVCaptureTorchModeOn];
[_captureDevice setFlashMode:AVCaptureFlashModeOn];
}
else {
_flashLightBtn.selected = NO;
[_captureDevice setTorchMode:AVCaptureTorchModeOff];
[_captureDevice setFlashMode:AVCaptureFlashModeOff];
}
[_captureDevice unlockForConfiguration];
[_captureSession commitConfiguration];
}
#else
[CommonUtil showAlert:G_ALERTTITLE withMessage:@"虛擬設(shè)備不能運(yùn)行攝像頭!"];
#endif
}
-(void)stopScanCode {
[_captureSession stopRunning];
_captureSession = nil;
_captureDevice = nil;
_captureInput = nil;
_captureOutput = nil;
[_capturePreview removeFromSuperlayer];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
@end
感謝閱讀,希望能幫助到大家,謝謝大家對(duì)本站的支持!
相關(guān)文章
iOS實(shí)現(xiàn)百度地圖拖拽后更新位置以及反編碼
百度地圖已經(jīng)開(kāi)放了地圖API,大家可以很方便的調(diào)用地圖中的相應(yīng)數(shù)據(jù),并完成各項(xiàng)個(gè)性化的展示,下面這篇文章主要給大家介紹了關(guān)于iOS如何實(shí)現(xiàn)百度地圖拖拽后更新位置以及反編碼的相關(guān)資料,需要的朋友可以參考借鑒,下面來(lái)一起看看吧。2017-12-12
ajax 三種實(shí)現(xiàn)方法實(shí)例代碼
這篇文章主要介紹了ajax 三種實(shí)現(xiàn)方法實(shí)例代碼的相關(guān)資料,需要的朋友可以參考下2016-09-09
IOS 播放系統(tǒng)提示音使用總結(jié)(AudioToolbox)
這篇文章主要介紹了IOS 播放系統(tǒng)提示音使用總結(jié)(AudioToolbox)的相關(guān)資料,需要的朋友可以參考下2017-05-05
iOS中定位(location manager )出現(xiàn)log日志的解決辦法
這篇文章主要給大家介紹了關(guān)于iOS中定位(location manager )出現(xiàn)log日志的解決辦法,文中通過(guò)示例代碼將解決的辦法介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。2017-10-10
解決iOS11圖片下拉放大出現(xiàn)信號(hào)欄白條的bug問(wèn)題
這篇文章主要介紹了iOS11圖片下拉放大出現(xiàn)信號(hào)欄白條的bug問(wèn)題,需要的朋友參考下吧2017-09-09
iOS開(kāi)發(fā)驗(yàn)證判斷語(yǔ)句之正則表達(dá)式小結(jié)
最近在公司接手重構(gòu)一個(gè)項(xiàng)目,發(fā)現(xiàn)之前的開(kāi)發(fā)在驗(yàn)證格式這塊寫(xiě)的太亂了,到處都有相關(guān)的驗(yàn)證代碼,所以就有了這篇文章,供自己收藏也分享給有需要的朋友們參考借鑒,下面跟著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。2016-12-12

