IOS中生成二維碼、掃描二維碼
阿新 • • 發佈:2019-01-09
轉載自: http://www.jianshu.com/p/b8bf300e9a56
- 從IOS7開始集成了二維碼的生成和讀取功能
生成二維碼
-
1 匯入CoreImage框架
#import <CoreImage/CoreImage.h>
-
2 通過濾鏡CIFilter生成二維碼
/**
* 生成二維碼
*/
- (void)creatCIQRCodeImage
{
// 1.建立過濾器,這裡的@"CIQRCodeGenerator"是固定的
CIFilter *filter = [CIFilter filterWithName:@"CIQRCodeGenerator"];
// 2.恢復預設設定
[filter setDefaults];
// 3. 給過濾器新增資料
NSString *dataString = @"二維碼測試資料";
NSData *data = [dataString dataUsingEncoding:NSUTF8StringEncoding];
// 注意,這裡的value必須是NSData型別
[filter setValue:data forKeyPath:@"inputMessage"];
// 4. 生成二維碼
CIImage *outputImage = [filter outputImage];
// 5. 顯示二維碼
self.imageView.image = [UIImage imageWithCIImage:outputImage];
}
- 通過上述方法生成的二維碼圖片比較模糊,第5步顯示二維碼的時候可以呼叫以下方法生成比較清晰的二維碼
/**
* 根據CIImage生成指定大小的UIImage
*
* @param image CIImage
* @param size 圖片寬度
*
* @return 生成高清的UIImage
*/
- (UIImage *)creatNonInterpolatedUIImageFormCIImage:(CIImage *)image withSize:(CGFloat )size
{
CGRect extent = CGRectIntegral(image.extent);
CGFloat scale = MIN(size/CGRectGetWidth(extent), size/CGRectGetHeight(extent));
// 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];
}
- 將上述生成高清二維碼的方法封裝成UIImage的Category如下
.h檔案
#import <UIKit/UIKit.h>
@interface UIImage (Category)
/**
* 根據CIImage生成指定大小的UIImage
*
* @param image CIImage
* @param size 圖片寬度
*
* @return 生成的高清的UIImage
*/
+ (UIImage *)creatNonInterpolatedUIImageFormCIImage:(CIImage *)image withSize:(CGFloat)size;
@end
.m檔案
#import "UIImage+Category.h"
@implementation UIImage (Category)
/**
* 根據CIImage生成指定大小的UIImage
*
* @param image CIImage
* @param size 圖片寬度
*
* @return 生成的高清的UIImage
*/
+ (UIImage *)creatNonInterpolatedUIImageFormCIImage:(CIImage *)image withSize:(CGFloat)size
{
CGRect extent = CGRectIntegral(image.extent);
CGFloat scale = MIN(size/CGRectGetWidth(extent), size/CGRectGetHeight(extent));
// 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];
}
@end
掃描二維碼
- 1 匯入
<AVFoundation/AVFoundation.h>
- 2 掃描二維碼實現
#import "ViewController.h"
// 匯入<AVFoundation/AVFoundation.h>框架
#import <AVFoundation/AVFoundation.h>
@interface ViewController ()<AVCaptureMetadataOutputObjectsDelegate>
/** 捕捉會話 */
@property (nonatomic, weak) AVCaptureSession *session;
/** 預覽圖層 */
@property (nonatomic, weak) AVCaptureVideoPreviewLayer *layer;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// 掃描二維碼
[self scanCIQRCode];
}
/**
* 掃描二維碼
*/
- (void)scanCIQRCode
{
// 1. 建立捕捉會話
AVCaptureSession *session = [[AVCaptureSession alloc] init];
self.session = session;
// 2. 新增輸入裝置(資料從攝像頭輸入)
AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:device error:nil];
[session addInput:input];
// 3. 新增輸出資料介面
AVCaptureMetadataOutput *output = [[AVCaptureMetadataOutput alloc] init];
// 設定輸出介面代理
[output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
[session addOutput:output];
// 3.1 設定輸入元資料的型別(型別是二維碼資料)
// 注意,這裡必須設定在addOutput後面,否則會報錯
[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) {// 掃描到了資料
AVMetadataMachineReadableCodeObject *object = [metadataObjects lastObject];
// 停止掃描
[self.session stopRunning];
// 將預覽圖層移除
[self.layer removeFromSuperlayer];
}else{
NSLog(@"沒有掃描到資料");
}
}
@end
文/袁俊亮技術部落格(簡書作者)
原文連結:http://www.jianshu.com/p/b8bf300e9a56
著作權歸作者所有,轉載請聯絡作者獲得授權,並標註“簡書作者”。