使用蘋果原生的框架實現二維碼的生成與掃描
#pragma mark -- 生成二維碼(普通/帶LOGO)
給NSString添加一個分類(分類下載地址: https://github.com/lieryang/Category/tree/master/Category)
NSString+EYQRCode.h
#import <Foundation/Foundation.h> #import <UIKit/UIKit.h> @interface NSString (EYQRCode) /** 根據字符串創建二維碼圖片 @param size 二維碼的大小 @return 生成的二維碼圖片 */ - (UIImage *)ey_createQRCodeImageWithSize:(CGFloat)size; /** 根據字符串創建帶logo的二維碼圖片 @param size 二維碼圖片總大小 @param logoImage logo圖片 @param logoSize 二維碼中的logo圖片大小 @return 生成的帶logo的二維碼圖片 */ - (UIImage *)ey_createQRCodeImageWithSize:(CGFloat)size withLogoImage:(UIImage *)logoImage withLogoSize:(CGFloat)logoSize;
NSString+EYQRCode.m
#import "NSString+EYQRCode.h" @implementation NSString (EYQRCode) #pragma mark - 外界調用接口 /** 根據字符串創建二維碼圖片 @param size 二維碼的大小 @return 生成的二維碼圖片 */ - (UIImage *)ey_createQRCodeImageWithSize:(CGFloat)size { //生成二維碼圖片 CIImage * ciImage = [self creatQRcodeWithUrlString:self]; //提高清晰度,修改二維碼大小 return [self createNonInterpolatedUIImageFormCIImage:ciImage withSize:size]; } /** 根據字符串創建帶logo的二維碼圖片 @param size 二維碼圖片總大小 @param logoImage logo圖片 @param logoSize 二維碼中的logo圖片大小 @return 生成的帶logo的二維碼圖片 */ - (UIImage *)ey_createQRCodeImageWithSize:(CGFloat)size withLogoImage:(UIImage *)logoImage withLogoSize:(CGFloat)logoSize { UIImage *superImage = [self ey_createQRCodeImageWithSize:size]; if (logoSize < 0) { return superImage; } else { return [self mergeImage:superImage withSubImage:logoImage withSubImageSize:logoSize]; } } #pragma mark - 內部使用的方法 /** 根據字符串生成二維碼 CIImage 對象 @param urlString 需要生成二維碼的字符串 @return 生成的二維碼 */ - (CIImage *)creatQRcodeWithUrlString:(NSString *)urlString { // 1.創建過濾器 CIQRCodeGenerator這個字符串是固定的不能修改為其他的字符串 CIFilter *filter = [CIFilter filterWithName:@"CIQRCodeGenerator"]; // 2.恢復濾鏡的默認屬性 (因為濾鏡有可能保存上一次的屬性) [filter setDefaults]; // 3.將字符串轉換成NSdata NSData *data = [urlString dataUsingEncoding:NSUTF8StringEncoding]; // 4.獲取輸出的二維碼 [filter setValue:data forKey:@"inputMessage"]; // 5.生成二維碼 CIImage *outputImage = [filter outputImage]; return outputImage; } /* 根據CIImage生成指定大小的UIImage 更加清晰 * * @param image CIImage * @param size 圖片寬度 */ - (UIImage *)createNonInterpolatedUIImageFormCIImage:(CIImage *)image withSize:(CGFloat)size { CGRect extent = CGRectIntegral(image.extent); CGFloat extentWidth = CGRectGetWidth(extent); CGFloat extentHeight = CGRectGetHeight(extent); if (size < extentWidth || size < extentHeight) { size = MIN(CGRectGetWidth(extent), CGRectGetHeight(extent)); } CGFloat scale = MIN(size/extentWidth, size/extentHeight); // 1.創建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); // 2.保存bitmap到圖片 CGImageRef scaledImage = CGBitmapContextCreateImage(bitmapRef); CGContextRelease(bitmapRef); CGImageRelease(bitmapImage); return [UIImage imageWithCGImage:scaledImage]; } /** 合並兩張圖片 @param superImage 底層圖片 @param subImage 上層圖片 @return 合並后的圖片 */ - (UIImage *)mergeImage:(UIImage *)superImage withSubImage:(UIImage *)subImage withSubImageSize:(CGFloat)subSize { UIGraphicsBeginImageContext(superImage.size); CGFloat superW = superImage.size.width; CGFloat superH = superImage.size.height; CGFloat subW = subSize; CGFloat subH = subSize; [superImage drawInRect:CGRectMake(0, 0, superW, superH)]; [subImage drawInRect:CGRectMake((superW - subW) / 2,(superH - subH) / 2, subW, subH)]; UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return image; } @end
使用如下: 不要忘記導入分類的頭文件呦 NSString+EYQRCode.h
//測試普通二維碼生成 self.QRCodeImageView.image = [@"www.baidu.com" ey_createQRCodeImageWithSize:200]; //測試logo二維碼生成 self.QRCodeImageView.image = [@"www.baidu.com" ey_createQRCodeImageWithSize:375 withLogoImage:[UIImage imageNamed:@"logo"] withLogoSize:50];
#pragma mark -- 掃描二維碼
#import "ViewController.h" #import <AVFoundation/AVFoundation.h> @interface ViewController ()<AVCaptureMetadataOutputObjectsDelegate> @property (nonatomic, strong) AVCaptureSession *session; @property (nonatomic, strong) AVCaptureVideoPreviewLayer *layer; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; // 1.創建捕捉會話 AVCaptureSession *session = [[AVCaptureSession alloc] init]; self.session = session; // 2.添加輸入設備(數據從攝像頭輸入) AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; AVAuthorizationStatus authStatus = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo]; if (authStatus == AVAuthorizationStatusRestricted || authStatus ==AVAuthorizationStatusDenied) { NSLog(@"沒有開啟攝像頭權限");//可以提示用戶開啟權限 return; } NSError * error = nil; AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:device error:&error]; if (error) { NSLog(@"沒有攝像頭或者攝像頭損壞或者沒有開啟攝像頭權限");//可以提示用戶 return; } [session addInput:input]; // 3.添加輸出數據(示例對象-->類對象-->元類對象-->根元類對象) AVCaptureMetadataOutput *output = [[AVCaptureMetadataOutput alloc] init]; [output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()]; [session addOutput:output]; // 3.1.設置輸入元數據的類型(類型是二維碼數據) [output setMetadataObjectTypes:@[AVMetadataObjectTypeQRCode]]; // 4.添加掃描圖層 AVCaptureVideoPreviewLayer *layer = [AVCaptureVideoPreviewLayer layerWithSession:session]; layer.frame = self.view.bounds; [self.view.layer addSublayer:layer]; self.layer = layer; // 5.開始掃描 [session startRunning]; } #pragma mark - AVCaptureMetadataOutputObjectsDelegate // 當掃描到數據時就會執行該方法 - (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection { if (metadataObjects.count > 0) { AVMetadataMachineReadableCodeObject *object = [metadataObjects lastObject]; // 可以跳轉界面 NSLog(@"掃描出來的字符串%@", object.stringValue); // 停止掃描 [self.session stopRunning]; // 將預覽圖層移除 [self.layer removeFromSuperlayer]; } else { NSLog(@"沒有掃描到數據"); } } @end
更多內容--> 博客導航 每周一篇喲!!!
有任何關於iOS開發的問題!歡迎下方留言!!!或者郵件lieryangios@126.com 雖然我不一定能夠解答出來,但是我會請教iOS開發高手!!!解答您的問題!!!
