用Swift写微信二维码
一.二维码概述
1.二维码的概念
二维码, 是用某种特定的几何图形按一定规律在平面(二维方向上)分布的黑白相间的图形记录数据符号信息的;
2.二维码的使用场景
● 信息获取(名片、地图、WIFI密码、资料)
● 网站跳转(跳转到微博、手机网站、网站)
● 广告推送(用户扫码,直接浏览商家推送的视频、音频广告)
● 手机电商(用户扫码、手机直接购物下单)
● 防伪溯源(用户扫码、即可查看生产地;同时后台可以获取最终消费地)
● 优惠促销(用户扫码,下载电子优惠券,抽奖)
● 会员管理(用户手机上获取电子会员信息、VIP服务)
● 手机支付(扫描商品二维码,通过银行或第三方支付提供的手机端通道完成支付)
3.生成二维码的方式
> 从iOS7开始集成了二维码的生成和读取功能
> 此前被广泛使用的zbarsdk目前不支持64位处理器
4.生成二维码的步骤
导入CoreImage框架 #import通过滤镜CIFilter生成二维码
> 1. 实例化二维码滤镜
CIFilter *filter = [CIFilter filterWithName:@"CIQRCodeGenerator"];
> 2. 恢复滤镜的默认属性
[filter setDefaults];
> 3. 将字符串转换成NSData
NSData *data = [@"小码哥" dataUsingEncoding:NSUTF8StringEncoding];
> 4. 通过KVC设置滤镜inputMessage数据
[filter setValue:data forKey:@"inputMessage"];
> 5. 获得滤镜输出的图像
CIImage *outputImage = [filter outputImage];
> 6. 将CIImage转换成UIImage,并放大显示
return [UIImage imageWithCIImage:outputImage scale:20.0 orientation:UIImageOrientationUp];
class GeneratorVC: UIViewController {@IBOutlet weak var inputTV: UITextView!@IBOutlet weak var qrCodeImageView: UIImageView! override func touchesBegan(touches: Set, withEvent event: UIEvent?) {
/** 友情提示: 学习实用技术, 不要太在意语言, 把所有注意力, 放在步骤的实现上面 */
let content = inputTV.text
// 生成二维码
// 1. 创建二维码滤镜
let filter = CIFilter(name: "CIQRCodeGenerator")
// 1.1 恢复滤镜默认设置
filter?.setDefaults()
// 2. 设置滤镜的输入内容
// 通过KVC 给里面一个inputMessage 赋值
// 输入的内容类型一定是NSData
let data = content.dataUsingEncoding(NSUTF8StringEncoding)
filter?.setValue(data, forKey: "inputMessage")
// 3. 从滤镜里面取出结果图片
// 3.1 注意: 取出的图片是ciimage, 并且大小是23* 23 所以需要我们单独处理
// (23.0, 23.0)
guard let outImage = filter?.outputImage else {
return
}
// 3.1 图片处理
// 使用这种方式, 可以把图片放大处理, 而且保证不失真
let transform = CGAffineTransformMakeScale(20, 20)
let resultImage = outImage.imageByApplyingTransform(transform)
// 把CIImage转换成为UIImage
let image = UIImage(CIImage: resultImage)
print(image.size)
// 4. 显示结果
qrCodeImageView.image = image
}
}
二.识别图片二维码
// 1. 创建一个二维码探测器
let detector = CIDetector(ofType: CIDetectorTypeQRCode, context: nil, options: [CIDetectorAccuracy : CIDetectorAccuracyHigh])
// 2. 探测二维码图片的特征
guard let image = qrCodeImage.image else {
return
}
let imageCI = CIImage(image: image)
let features = detector.featuresInImage(imageCI!)
// 3. 处理识别到的特征值
print(features)
for feature in features {
if feature.isKindOfClass(CIQRCodeFeature) {
let qrCodeFeature = feature as! CIQRCodeFeature
print(qrCodeFeature.messageString)
// 绘制识别到的二维码图片
}
}
}
三.读取二维码
读取二维码需要导入AVFoundation框架
利用摄像头识别二维码中的内容(模拟器不行)
实例化拍摄设备
AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
设置输入设备
AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:device error:nil];
设置元数据输出
3.1 实例化拍摄元数据输出
AVCaptureMetadataOutput *output = [[AVCaptureMetadataOutput alloc] init];
3.2 设置输出数据代理
[output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
3.3 设置扫描取景范围(rectOfInterest 都是按照横屏来计算的 所以当竖屏的情况下 x轴和y轴要交换一下)
CGFloat screenW = [UIScreen mainScreen].bounds.size.width;
CGFloat screenH = [UIScreen mainScreen].bounds.size.height;
CGFloat scanW = screenW * 0.6;
CGRect scanRect = CGRectMake((screenW - scanW) * 0.5, (screenH - scanW) * 0.5, scanW, scanW);
output.rectOfInterest = CGRectMake(scanRect.origin.y / screenH, scanRect.origin.x / screenW, scanRect.size.height / screenH, scanRect.size.width / screenW);
3.4 设置扫描区域的边框
UIView *scanV = [[UIView alloc] initWithFrame:scanRect];
[self.view addSubview:scanV];
scanV.layer.borderWidth = 2;
scanV.layer.borderColor = [UIColor redColor].CGColor;
添加拍摄会话
4.1 实例化拍摄会话
AVCaptureSession *session = [[AVCaptureSession alloc] init];
4.2 添加会话输入
[session addInput:input];
4.3 添加会话输出
[session addOutput:output];
4.3 设置输出数据类型,需要将元数据输出添加到会话后,才能指定元数据类型,否则会报错
[output setMetadataObjectTypes:@[AVMetadataObjectTypeQRCode]];
视频预览图层
5.1 实例化预览图层
AVCaptureVideoPreviewLayer *preview = [AVCaptureVideoPreviewLayer layerWithSession:_session];
preview.videoGravity = AVLayerVideoGravityResizeAspectFill;
preview.frame = self.view.bounds;
5.2 将图层插入当前视图
[self.view.layer addSublayer:preview];
self.previewLayer = preview;
启动会话
[_session startRunning];