偶尔用这一块的东西,总是记不住,所以写了两个demo 注释写的非常详细.
二维码的生成:
#import "ViewController.h" #import <CoreImage/CoreImage.h> @interface ViewController () @property (weak, nonatomic) IBOutlet UIImageView *codeImage; @end /* 1. 生成二维码 要导入CoreImage 这个系统原生框架 (因为要去获取内置滤镜 支持各种种类的二维码) 2. ( inputMessage, 链接的字符串 (输入的 就是咱们自己去设定的) inputCorrectionLevel 链接类型 ) 3. 要记住 扫二维码 是一个操作 根据得到的这个字符串的类型 去让他去做下一步的操作. 4.filter.outputImage 得到图片 5.调整清晰度 */ @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; // 1. 创建滤镜对象 内置滤镜 支持各种种类的二维码 跟一个类型 具体什么格式 不清楚 // 通过一个分类的属性 来进行打印 打印所有的对象 // NSLog(@"%@",[CIFilter filterNamesInCategory:kCICategoryBuiltIn]); // 二维码滤镜已经获取 CIFilter *filter = [CIFilter filterWithName:@"CIQRCodeGenerator"]; // 2. 设置默认值 [filter setDefaults]; // 3.输入字符串 NSLog(@"%@",filter.inputKeys); // 完全可以吧这个字符串去看做是一个特殊的字符串类型 // 只读属性 利用KVC 进行复制 // CIQRCodeGenerator filter requires NSData for inputMessage 这个哥们必须是一个二维码 // 将字符串 转换成2进制的方法 [filter setValue:[@"http://mp.weixin.qq.com/wiki/14/9f9c82c1af308e3b14ba9b973f99a8ba.html" dataUsingEncoding:NSUTF8StringEncoding] forKey:@"inputMessage"]; NSLog(@"%@",filter.inputKeys); // 5.放大图片 CIImage 是继承自NSObject (原因:CIImage 确实是放大了五倍,然后CodeImageFrame没有改变,像素点密集 变得清晰) CIImage *resultImage = [filter.outputImage imageByApplyingTransform:CGAffineTransformMakeScale(5, 5)]; self.codeImage.image = [UIImage imageWithCIImage:resultImage]; // // 4.获取二维码的图片 // CIImage *imageC = filter.outputImage; // // self.codeImage.image = [UIImage imageWithCIImage:imageC]; // } @end
二维码的读取:
#import "ViewController.h" #import <AVFoundation/AVFoundation.h> @interface ViewController ()<AVCaptureMetadataOutputObjectsDelegate> @property (nonatomic,strong)AVCaptureSession *session; @property (nonatomic,strong)AVCaptureDeviceInput *input; @property (nonatomic,strong)AVCaptureMetadataOutput *output; // 创建预览视图 layer层 专门用来显示输入设备来捕捉到的画面 @property (nonatomic,strong)AVCaptureVideoPreviewLayer *viewLayer; // 继承自CALayer @end /* 1.导入AVFoundtation 框架 输入设备 相机 麦克 键盘等 AVCaptureDeviceInput(子类) AVCaptureInput(父类) 输出设备 解析 (元数据) AVCaptureMetadataOutput -> AVCaptureOutput 会话链接 将输入设备和输出设备去建立联系 二维码的扫码和屏幕显示的东西都是没有关系的,只是和摄像头对准的二维码有关 至于后来的页面跳转和别的操作 就是其他的业务逻辑 咱们只是拿到数据之后 对这个字符串去进行分析 格式 元数据: 元数据(MetaData) 因为它们是用来描述具体数据/信息的数据/信息。 在日常生活中,元数据无所不在。有一类事物,就可以定义一套元数据。 元数据最大的好处是,它使信息的描述和分类可以实现格式化,从而为机器处理创造了可能。 1. 创建输入设备对象 AVCaptureDeviceInput 并且设置好设备类型 2,创建输出设备对象 AVCaptureMetadataOutput (元数据对象) 3. 创建 AVCaptureSession 对象 将输入输出(添加)建立联系 4. 设置视频范围 [self.session setSessionPreset:AVCaptureSessionPresetHigh]; 5.开启 6,设置 AVCaptureMetadataOutput 的数据 并获取对象.. ( 7. 设置输出设备的类型 (注意 有坑) */ /* 输出设备的与数据得到可用参数 ( "org.iso.Aztec", "org.iso.Code128", "org.iso.Code39", "org.iso.Code39Mod43", "com.intermec.Code93", "org.iso.DataMatrix", "org.gs1.EAN-13", "org.gs1.EAN-8", "org.ansi.Interleaved2of5", "org.gs1.ITF14", "org.iso.PDF417", "org.iso.QRCode", 二维码 类型 "org.gs1.UPC-E", face ) */ @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; } - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{ // 1 创建输入设备 (类型为相机) // 给定一个设备 让咱们知道是哪个设备 AVMediaTypeVideo 就是这个样式的的字符串 ?? // 元数据 AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; self.input = [[AVCaptureDeviceInput alloc]initWithDevice:device error:nil]; // 2, 创建输出设备 用来去解析 self.output = [[AVCaptureMetadataOutput alloc]init]; // ?? // 2,1 设置输出设备的代理 (这个地方的代理设置的地放比较特殊) // 这个地方为什么要去设置一个全局队列 [ self.output setMetadataObjectsDelegate:self queue:dispatch_get_global_queue(0, 0)]; // //6. 设置元数据类型区别的 // // 先去打印一下可用类型有哪些 (7.0 之前 和7.0 之后 这个地方是有) // NSLog(@"%@",self.output.metadataObjectTypes); // 元数据可以利用的数据类型 // // 3. 创建会话层 建立联系 self.session = [[AVCaptureSession alloc]init]; // 3.1 先判断能否添加 设备 然后添加 if ([self.session canAddInput:self.input]) { [self.session addInput:self.input]; } if ([self.session canAddOutput:self.output]) { [self.session addOutput:self.output]; } // 5, 设置视频范围 //[self.session setSessionPreset:AVCaptureSessionPresetHigh]; // high 是自适应的 [self.session setSessionPreset:AVCaptureSessionPresetHigh]; //6. 设置元数据类型 // 先去打印一下可用类型有哪些 NSLog(@"%@",self.output.availableMetadataObjectTypes); // 元数据可以利用的数据类型 // 根据类型去进行设置 [self.output setMetadataObjectTypes:@[AVMetadataObjectTypeQRCode]]; // 4. 开启会话 [self.session startRunning]; // 8. 增加一个预览视图 用来去显示输入设备的画面 // 创建 self.viewLayer = [[AVCaptureVideoPreviewLayer alloc]initWithSession:self.session]; // 设置frame self.viewLayer.frame = self.view.bounds; // [self.view addSubview:self.viewLayer]; 继承自CALayer [self.view.layer addSublayer:self.viewLayer]; } #pragma mark -- 代理的方法 解析数据的时候就会去调用这个方法 // 数据解析完成之后 会给你返回一个字符串 - (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection{ // 扫描的数据全部都放在 metadataObjects 既然是数组 那么久先去打印他 //NSLog(@"%@",metadataObjects); //取出扫描的数据 AVMetadataMachineReadableCodeObject *objc = [metadataObjects firstObject]; NSLog(@"%@",objc.stringValue); // 关闭会话 [self.session stopRunning]; // 移除这个层 [self.viewLayer removeFromSuperlayer]; } @end
时间: 2024-10-08 20:50:19