iOS 原生二维码扫描、生成、识别
来源:互联网 发布:手机淘宝哪里投诉卖家 编辑:程序博客网 时间:2024/04/30 08:43
一、二维码生成
#import <Foundation/Foundation.h>
#import <CoreImage/CoreImage.h>@interface BYCQRCodeTool : NSObject
/** 生成一张普通的二维码 */
+ (UIImage *)SG_generateWithDefaultQRCodeData:(NSString *)data imageViewWidth:(CGFloat)imageViewWidth;
/** 生成一张带有logo的二维码(logoScaleToSuperView:相对于父视图的缩放比取值范围0-1;0,不显示,1,代表与父视图大小相同) */
+ (UIImage *)SG_generateWithLogoQRCodeData:(NSString *)data logoImageName:(NSString *)logoImageName logoScaleToSuperView:(CGFloat)logoScaleToSuperView;
/** 生成一张彩色的二维码 */
+ (UIImage *)SG_generateWithColorQRCodeData:(NSString *)data backgroundColor:(CIColor *)backgroundColor mainColor:(CIColor *)mainColor;
@end
#import "BYCQRCodeTool.h"
@implementation BYCQRCodeTool
/**
* 生成一张普通的二维码
*
* @param data 传入你要生成二维码的数据
* @param imageViewWidth 图片的宽度
*/
+ (UIImage *)SG_generateWithDefaultQRCodeData:(NSString *)data imageViewWidth:(CGFloat)imageViewWidth {
// 1、创建滤镜对象
CIFilter *filter = [CIFilter filterWithName:@"CIQRCodeGenerator"];
// 恢复滤镜的默认属性
[filter setDefaults];
// 2、设置数据
NSString *info = data;
// 将字符串转换成
NSData *infoData = [info dataUsingEncoding:NSUTF8StringEncoding];
// 通过KVC设置滤镜inputMessage数据
[filter setValue:infoData forKeyPath:@"inputMessage"];
// 3、获得滤镜输出的图像
CIImage *outputImage = [filter outputImage];
return [BYCQRCodeTool createNonInterpolatedUIImageFormCIImage:outputImage withSize:imageViewWidth];
}
/** 根据CIImage生成指定大小的UIImage */
+ (UIImage *)createNonInterpolatedUIImageFormCIImage:(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];
}
/**
* 生成一张带有logo的二维码
*
* @param data 传入你要生成二维码的数据
* @param logoImageName logo的image名
* @param logoScaleToSuperView logo相对于父视图的缩放比(取值范围:0-1,0,代表不显示,1,代表与父视图大小相同)
*/
+ (UIImage *)SG_generateWithLogoQRCodeData:(NSString *)data logoImageName:(NSString *)logoImageName logoScaleToSuperView:(CGFloat)logoScaleToSuperView {
// 1、创建滤镜对象
CIFilter *filter = [CIFilter filterWithName:@"CIQRCodeGenerator"];
// 恢复滤镜的默认属性
[filter setDefaults];
// 2、设置数据
NSString *string_data = data;
// 将字符串转换成 NSdata (虽然二维码本质上是字符串, 但是这里需要转换, 不转换就崩溃)
NSData *qrImageData = [string_data dataUsingEncoding:NSUTF8StringEncoding];
// 设置过滤器的输入值, KVC赋值
[filter setValue:qrImageData forKey:@"inputMessage"];
// 3、获得滤镜输出的图像
CIImage *outputImage = [filter outputImage];
// 图片小于(27,27),我们需要放大
outputImage = [outputImage imageByApplyingTransform:CGAffineTransformMakeScale(20, 20)];
// 4、将CIImage类型转成UIImage类型
UIImage *start_image = [UIImage imageWithCIImage:outputImage];
// - - - - - - - - - - - - - - - - 添加中间小图标 - - - - - - - - - - - - - - - -
// 5、开启绘图, 获取图形上下文 (上下文的大小, 就是二维码的大小)
UIGraphicsBeginImageContext(start_image.size);
// 把二维码图片画上去 (这里是以图形上下文, 左上角为(0,0)点
[start_image drawInRect:CGRectMake(0, 0, start_image.size.width, start_image.size.height)];
// 再把小图片画上去
NSString *icon_imageName = logoImageName;
UIImage *icon_image = [UIImage imageNamed:icon_imageName];
CGFloat icon_imageW = start_image.size.width * logoScaleToSuperView;
CGFloat icon_imageH = start_image.size.height * logoScaleToSuperView;
CGFloat icon_imageX = (start_image.size.width - icon_imageW) * 0.5;
CGFloat icon_imageY = (start_image.size.height - icon_imageH) * 0.5;
[icon_image drawInRect:CGRectMake(icon_imageX, icon_imageY, icon_imageW, icon_imageH)];
// 6、获取当前画得的这张图片
UIImage *final_image = UIGraphicsGetImageFromCurrentImageContext();
// 7、关闭图形上下文
UIGraphicsEndImageContext();
return final_image;
}
/**
* 生成一张彩色的二维码
*
* @param data 传入你要生成二维码的数据
* @param backgroundColor 背景色
* @param mainColor 主颜色
*/
+ (UIImage *)SG_generateWithColorQRCodeData:(NSString *)data backgroundColor:(CIColor *)backgroundColor mainColor:(CIColor *)mainColor {
// 1、创建滤镜对象
CIFilter *filter = [CIFilter filterWithName:@"CIQRCodeGenerator"];
// 恢复滤镜的默认属性
[filter setDefaults];
// 2、设置数据
NSString *string_data = data;
// 将字符串转换成 NSdata (虽然二维码本质上是字符串, 但是这里需要转换, 不转换就崩溃)
NSData *qrImageData = [string_data dataUsingEncoding:NSUTF8StringEncoding];
// 设置过滤器的输入值, KVC赋值
[filter setValue:qrImageData forKey:@"inputMessage"];
// 3、获得滤镜输出的图像
CIImage *outputImage = [filter outputImage];
// 图片小于(27,27),我们需要放大
outputImage = [outputImage imageByApplyingTransform:CGAffineTransformMakeScale(9, 9)];
// 4、创建彩色过滤器(彩色的用的不多)
CIFilter * color_filter = [CIFilter filterWithName:@"CIFalseColor"];
// 设置默认值
[color_filter setDefaults];
// 5、KVC 给私有属性赋值
[color_filter setValue:outputImage forKey:@"inputImage"];
// 6、需要使用 CIColor
[color_filter setValue:backgroundColor forKey:@"inputColor0"];
[color_filter setValue:mainColor forKey:@"inputColor1"];
// 7、设置输出
CIImage *colorImage = [color_filter outputImage];
return [UIImage imageWithCIImage:colorImage];
}
二、识别
//1. 初始化扫描仪,设置设别类型和识别质量
CIDetector*detector = [CIDetector detectorOfType:CIDetectorTypeQRCode context:nil options:@{ CIDetectorAccuracy : CIDetectorAccuracyHigh }];
//2. 扫描获取的特征组
NSArray *features = [detector featuresInImage:[CIImage imageWithCGImage:tempImageView.image.CGImage]];
//3. 获取扫描结果
CIQRCodeFeature *feature = [features objectAtIndex:0];
NSString *scannedResult = feature.messageString;
三、扫描
// 1、获取摄像设备
AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
// 2、创建输入流
AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:device error:nil];
// 3、创建输出流
AVCaptureMetadataOutput *output = [[AVCaptureMetadataOutput alloc] init];
// 4、设置代理 在主线程里刷新
[output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
// 设置扫描范围(每一个取值0~1,以屏幕右上角为坐标原点)
// 注:微信二维码的扫描范围是整个屏幕,这里并没有做处理(可不用设置)
output.rectOfInterest = CGRectMake(0.05, 0.2, 0.7, 0.6);
// 5、初始化链接对象(会话对象)
self.session = [[AVCaptureSession alloc] init];
// 高质量采集率
[_session setSessionPreset:AVCaptureSessionPresetHigh];
// 5.1 添加会话输入
[_session addInput:input];
// 5.2 添加会话输出
[_session addOutput:output];
// 6、设置输出数据类型,需要将元数据输出添加到会话后,才能指定元数据类型,否则会报错
// 设置扫码支持的编码格式(如下设置条形码和二维码兼容)
output.metadataObjectTypes = @[AVMetadataObjectTypeQRCode, AVMetadataObjectTypeEAN13Code, AVMetadataObjectTypeEAN8Code, AVMetadataObjectTypeCode128Code];
// 7、实例化预览图层, 传递_session是为了告诉图层将来显示什么内容
self.previewLayer = [AVCaptureVideoPreviewLayer layerWithSession:_session];
_previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
_previewLayer.frame = self.view.layer.bounds;
// 8、将图层插入当前视图
[self.view.layer insertSublayer:_previewLayer atIndex:0];
// 9、启动会话
[_session startRunning];
- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection {
// 会频繁的扫描,调用代理方法
// 0、扫描成功之后的提示音
[self playSoundEffect:@"sound.caf"];
// 1、如果扫描完成,停止会话
[self.session stopRunning];
// 2、删除预览图层
[self.previewLayer removeFromSuperlayer];
// 3、设置界面显示扫描结果
if (metadataObjects.count > 0) {
AVMetadataMachineReadableCodeObject *obj = metadataObjects[0];
NSLog(@"metadataObjects = %@", metadataObjects);
if ([obj.stringValue hasPrefix:@"http"]) {
// 扫描结果为http跳转
} else {
// 扫描结果为条形码
}
}
}
- iOS 原生二维码扫描、生成、识别
- iOS原生二维码扫描&libqrencode生成二维码
- ios 原生二维码的扫描和生成
- iOS之长按识别二维码/生成二维码/扫描二维码
- iOS原生二维码扫描
- iOS 原生二维码扫描
- iOS:原生二维码扫描
- iOS原生二维码扫描
- iOS原生扫描二维码
- ios原生二维码扫描
- iOS:原生二维码扫描
- ios原生二维码扫描
- iOS 原生二维码扫描
- iOS 原生二维码扫描
- iOS 原生扫描二维码
- iOS原生二维码扫描
- iOS开发--生成二维码及扫描二维码(原生)
- iOS原生二维码生成与扫描以及条形码的扫描
- onInterceptTouchEvent和onTouchEvent调用关系详解
- 20. Valid Parentheses
- idea常用快捷键设置(改为eclipse相似)
- MySQL服务器参数优化
- js去重
- iOS 原生二维码扫描、生成、识别
- Linux中的grep命令实例
- 安装mysql报错问题处理
- windows下Gulp入门详细教程
- Ubuntu 14.04 64 bit error while loading shared libraries: libgtk-x11-2.0.so.0
- STL迭代器的分类
- Spring和MyBatis环境整合
- 获取指定Date区间内所有月份
- 用eclipse导出webserver客户端代码