iOS开发生成二维码与扫描二维码
生成二维码:
.h文件
#import@interface NPDFgenerationOfQRCode : NSObject
- (UIImage *)buildQRcodeForString:(NSString *)qrCodeString accordingSize:(CGFloat)size;
@end
.m文件
#import "NPDFgenerationOfQRCode.h"#import@implementation NPDFgenerationOfQRCode
-(instancetype)init
{
self = [super init];
if (self) {
}
return self;
}
- (UIImage *)buildQRcodeForString:(NSString *)qrCodeString accordingSize:(CGFloat)size{
UIImage *codeImage = [self createNonInterpolatedUIImageFormCIImage:[self createQRCodeForString:qrCodeString] withSize:size];
return codeImage;
}
- (CIImage *)createQRCodeForString:(NSString *)qrCodeString
{
//创建二维码需要保存的数据
NSData *stringData = [qrCodeString dataUsingEncoding:NSUTF8StringEncoding];
// 创建filter
CIFilter *qrFilter = [CIFilter filterWithName:@"CIQRCodeGenerator"];
//清空滤镜
[qrFilter setDefaults];
// 设置内容和纠错级别
[qrFilter setValue:stringData forKey:@"inputMessage"];
[qrFilter setValue:@"H" forKey:@"inputCorrectionLevel"];
// 返回CIImage
return qrFilter.outputImage;
}
- (UIImage *)createNonInterpolatedUIImageFormCIImage:(CIImage *)image withSize:(CGFloat) size {
CGRect extent = CGRectIntegral(image.extent);
CGFloat scale = MIN(size/CGRectGetWidth(extent), size/CGRectGetHeight(extent));
// 创建bitmap;
size_t width = CGRectGetWidth(extent) * scale;
size_t height = CGRectGetHeight(extent) * scale;
CGColorSpaceRef cs = CGColorSpaceCreateDeviceGray();
CGContextRef bitmapRef = CGBitmapContextCreate(nil, width, height, 8, 0, cs, (CGBitmapInfo)kCGImageAlphaNone);
CIContext *context = [CIContext contextWithOptions:nil];
CGImageRef bitmapImage = [context createCGImage:image fromRect:extent];
CGContextSetInterpolationQuality(bitmapRef, kCGInterpolationNone);
CGContextScaleCTM(bitmapRef, scale, scale);
CGContextDrawImage(bitmapRef, extent, bitmapImage);
// 保存bitmap到图片
CGImageRef scaledImage = CGBitmapContextCreateImage(bitmapRef);
CGContextRelease(bitmapRef);
CGImageRelease(bitmapImage);
return [UIImage imageWithCGImage:scaledImage];
}
@end
扫描二维码:
.h文件
#import "DFBaseViewController.h"
typedef NS_ENUM(NSInteger, DFChooseScanType) {
DFChooseScanTypeYanquan = 1,//验券
};
@interface DFScanMaViewController : NPBaseViewController
@property (nonatomic, assign)DFChooseScanType type;
@end
.m文件
#import "DFScanMaViewController.h"
#define scan height 250
#define top height 100
// 屏幕宽高
#define NPAPPWidth [UIScreen mainScreen].bounds.size.width
#define NPAPPHeight [UIScreen mainScreen].bounds.size.height
@interface NPScanMaViewController (){
AVCaptureSession * _session;
AVCaptureVideoPreviewLayer * _layer;
AVCaptureMetadataOutput * _output;
AVCaptureDeviceInput * _input;
UIView * _superView;
int line_tag;
NSString*string;
}
@end
@implementation DFScanMaViewController
- (void)viewDidLoad {
[super viewDidLoad];
string=[NSString string];
line_tag = 1872637;
// Do any additional setup after loading the view from its nib.
[DFNavigationPublic setTitleOnTargetNav:self title:@"扫码"];
[DFNavigationPublic setBackButtonOnTargetNav:self action:@selector(selfRemoveFromSuperview)];
//判断相机权限
NSString *mediaType = AVMediaTypeVideo;
AVAuthorizationStatus authStatus = [AVCaptureDevice authorizationStatusForMediaType:mediaType];
if(authStatus == AVAuthorizationStatusNotDetermined || authStatus == AVAuthorizationStatusDenied){
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"相机权限受限" message:@"请在iPhone的\"设置->隐私->相机\"选项中,允许\"哪拍\"访问您的相机." delegate:nil cancelButtonTitle:@"好的" otherButtonTitles:nil];
[alert show];
[self.navigationController popViewControllerAnimated:YES];
return;
}
CGSize scanSize=CGSizeMake(scanheight, scanheight);
CGRect scanRect=CGRectMake((NPAPPWidth-scanSize.width)/2, (NPAPPHeight-scanSize.width)/2-topheight, scanSize.width, scanSize.height);
UIView * scanRectView=[UIView new];
scanRectView.layer.borderColor=[UIColor whiteColor].CGColor;
scanRectView.layer.borderWidth=0.5;
//初始化链接对象
_session = [[AVCaptureSession alloc]init];
//高质量采集率
if([_session canSetSessionPreset:AVCaptureSessionPreset1920x1080] == YES ) {
_session.sessionPreset = AVCaptureSessionPreset1920x1080;
}else if (([_session canSetSessionPreset:AVCaptureSessionPreset1280x720] == YES )){
_session.sessionPreset = AVCaptureSessionPreset1280x720;
} else {
_session.sessionPreset = AVCaptureSessionPreset640x480;
}
//获取摄像设备
AVCaptureDevice * device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
//创建输入流
_input = [AVCaptureDeviceInput deviceInputWithDevice:device error:nil];
[_session addInput:_input];
//创建输出流
_output = [[AVCaptureMetadataOutput alloc]init];
//设置代理 在主线程里刷新
[_output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
[_session addOutput:_output];
_output.metadataObjectTypes=@[AVMetadataObjectTypeQRCode,AVMetadataObjectTypeEAN13Code, AVMetadataObjectTypeEAN8Code, AVMetadataObjectTypeCode128Code];
_layer=[AVCaptureVideoPreviewLayer layerWithSession:_session];
_layer.videoGravity=AVLayerVideoGravityResizeAspectFill;
[self showLayer:self.view];
[self setOverlayPickerView];
[self setScanningRect:scanRect scanView:scanRectView];
}
-(void)showLayer:(UIView *)superView
{
_superView=superView;
_layer.frame=superView.layer.frame;
[self.view.layer insertSublayer:_layer atIndex:0];
}
- (void)setOverlayPickerView
{
//左侧的view
UIImageView *leftView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, (NPAPPWidth-scanheight)/2, NPAPPHeight)];
leftView.alpha = 0.5;
leftView.backgroundColor = [UIColor blackColor];
[self.view addSubview:leftView];
//右侧的view
UIImageView *rightView = [[UIImageView alloc] initWithFrame:CGRectMake((NPAPPWidth-scanheight)/2+scanheight, 0, (NPAPPWidth-scanheight)/2, NPAPPHeight)];
rightView.alpha = 0.5;
rightView.backgroundColor = [UIColor blackColor];
[self.view addSubview:rightView];
//最上部view
UIImageView* upView = [[UIImageView alloc] initWithFrame:CGRectMake((NPAPPWidth-scanheight)/2, 0, scanheight, (NPAPPHeight-scanheight)/2-topheight)];
upView.alpha = 0.5;
upView.backgroundColor = [UIColor blackColor];
[self.view addSubview:upView];
//底部view
UIImageView * downView = [[UIImageView alloc] initWithFrame:CGRectMake((NPAPPWidth-scanheight)/2,(NPAPPHeight-scanheight)/2-topheight+scanheight, scanheight, NPAPPHeight-200)];
downView.alpha = 0.5;
downView.backgroundColor = [UIColor blackColor];
[self.view addSubview:downView];
UIImageView *centerView = [[UIImageView alloc] initWithFrame:CGRectMake((NPAPPWidth-scanheight)/2, (NPAPPHeight-scanheight)/2-topheight,scanheight,scanheight)];
centerView.image = [UIImage imageNamed:@"saomiaokuang"];
centerView.contentMode = UIViewContentModeScaleAspectFit;
centerView.backgroundColor = [UIColor clearColor];
[self.view addSubview:centerView];
UIImageView *line = [[UIImageView alloc] initWithFrame:CGRectMake((NPAPPWidth-scanheight)/2, CGRectGetMaxY(upView.frame), scanheight, 2)];
line.tag = line_tag;
line.image = [UIImage imageNamed:@"saomiaoline"];
line.contentMode = UIViewContentModeScaleAspectFill;
line.backgroundColor = [UIColor clearColor];
[self.view addSubview:line];
UILabel *msg = [[UILabel alloc] initWithFrame:CGRectMake(30, CGRectGetMinY(downView.frame), NPAPPWidth-60, 60)];
msg.backgroundColor = [UIColor clearColor];
msg.textColor = [UIColor whiteColor];
msg.textAlignment = NSTextAlignmentCenter;
msg.font = [UIFont systemFontOfSize:16];
msg.text = @"将二维码放入框内,即可自动扫描";
[self.view addSubview:msg];
}
-(void)starttRunning{
[_session addObserver:self forKeyPath:@"running" options:NSKeyValueObservingOptionNew context:nil];
[_session startRunning];
}
-(void)stoppRunning{
[_session stopRunning];
[_session removeObserver:self forKeyPath:@"running" context:nil];
}
-(void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection{
if (metadataObjects.count>0) {
[self stoppRunning];
AVMetadataMachineReadableCodeObject * metadataObject = [metadataObjects objectAtIndex : 0 ];
//输出扫描字符串
string =metadataObject.stringValue;
[self performSelector:@selector(gotoScanwith) withObject:nil afterDelay:0.5];
}
}
-(void)gotoScanwith
{
if (self.type==DFChooseScanTypeYanquan) {
NSArray * objectarray = [string componentsSeparatedByString:@","]; //从字符A中分隔成2个元素的数组
}else{
}
}
-(void)removeLayer:(UIView *)superView
{
[_layer removeFromSuperlayer];
}
-(void)setScanningRect:(CGRect)scanRect scanView:(UIView *)scanView
{
CGFloat x,y,width,height;
x=((NPAPPHeight-scanheight)/2-topheight+64)/NPAPPHeight;
y=((NPAPPWidth-scanheight)/2)/NPAPPWidth;
width=scanheight/NPAPPHeight;
height=scanheight/NPAPPWidth;
_output.rectOfInterest=CGRectMake(0, 0, 1, 1);
// _output.rectOfInterest=CGRectMake(x, y, width, height);
if (scanView) {
scanView.frame=scanRect;
if (_superView) {
[_superView addSubview:scanView];
}
}
}
- (void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary *)change
context:(void *)context{
if ([object isKindOfClass:[AVCaptureSession class]]) {
BOOL isRunning = ((AVCaptureSession *)object).isRunning;
if (isRunning) {
[self addAnimation];
}else{
[self removeAnimation];
}
}
}
//添加扫描动画
- (void)addAnimation{
UIView *line = [self.view viewWithTag:line_tag];
line.hidden = NO;
CABasicAnimation *animation = [NPScanMaViewController moveYTime:2 fromY:[NSNumber numberWithFloat:0] toY:[NSNumber numberWithFloat:scanheight] rep:OPEN_MAX];
[line.layer addAnimation:animation forKey:@"LineAnimation"];
}
- (void)removeAnimation{
UIView *line = [self.view viewWithTag:line_tag];
[line.layer removeAnimationForKey:@"LineAnimation"];
line.hidden = YES;
}
+ (CABasicAnimation *)moveYTime:(float)time fromY:(NSNumber *)fromY toY:(NSNumber *)toY rep:(int)rep
{
CABasicAnimation *animationMove = [CABasicAnimation animationWithKeyPath:@"transform.translation.y"];
[animationMove setFromValue:fromY];
[animationMove setToValue:toY];
animationMove.duration = time;
animationMove.delegate = self;
animationMove.repeatCount = rep;
animationMove.fillMode = kCAFillModeForwards;
animationMove.removedOnCompletion = NO;
animationMove.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
return animationMove;
}
- (void)selfRemoveFromSuperview{
[self stoppRunning];
[UIView animateWithDuration:0.3 delay:0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
self.view.alpha = 0;
} completion:^(BOOL finished) {
[self.view removeFromSuperview];
[self removeFromParentViewController];
}];
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleDefault animated:YES];
[self.navigationController popViewControllerAnimated:YES];
}
-(void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:YES];
[self starttRunning];
}