1.扫描二维码的实现
//导入框架
#import <AVFoundation/AVFoundation.h>
链接代理AVCaptureMetadataOutputObjectsDelegate
声明定时器和上下移动的线条
NSTimer * timer;
UIView * lineView;
@property (nonatomic, strong) AVCaptureSession * captureSession;
@property (nonatomic, strong) AVCaptureVideoPreviewLayer * videoPreviewLayer;
@property (nonatomic, assign) BOOL lastResult;
@property (weak, nonatomic) IBOutlet UIView *myView;//此View是扫描的方框
#pragma mark == 创建会话,读取输入流
- (BOOL)startReading
{
//获取AVCaptureDevice的实例
NSError * error;
AVCaptureDevice * captureDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
//初始化输入流
AVCaptureDeviceInput * input = [AVCaptureDeviceInput deviceInputWithDevice:captureDevice error:&error];
if (!input) {
NSLog(@"%@", [error localizedDescription]);
return NO;
}
//创建会话
_captureSession = [[AVCaptureSession alloc]init];
//添加输入流
[_captureSession addInput:input];
//输出流
AVCaptureMetadataOutput * captureMetadataOutput = [[AVCaptureMetadataOutput alloc] init];
// 输出流
[_captureSession addOutput:captureMetadataOutput];
//创建队列
dispatch_queue_t dispatchQueue;
dispatchQueue = dispatch_queue_create(kScanQRCodeQueueName, NULL);
[captureMetadataOutput setMetadataObjectsDelegate:self queue:dispatchQueue];
// 设置元数据类型为 AVMetadataObjectTypeQRCode
[captureMetadataOutput setMetadataObjectTypes:[NSArray arrayWithObject:AVMetadataObjectTypeQRCode]];
// 输出对象
_videoPreviewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:_captureSession];
[_videoPreviewLayer setVideoGravity:AVLayerVideoGravityResizeAspectFill];
//边框
self.myView.layer.borderColor = [UIColor orangeColor].CGColor;
self.myView.layer.borderWidth = 1;
//动画
timer = [NSTimer timerWithTimeInterval:0 target:self selector:@selector(scanCodeAnimation:) userInfo:self repeats:YES];
[[NSRunLoop mainRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];
[timer fire];
[_videoPreviewLayer setFrame:self.myView.layer.bounds];
[self.myView.layer addSublayer:_videoPreviewLayer];
//添加横线
lineView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 200, 1)];
lineView.backgroundColor = [UIColor orangeColor];
[self.myView addSubview:lineView];
// 开始
[_captureSession startRunning];
return YES;
}
- (void)scanCodeAnimation:(NSTimer *)time
{
[UIView animateWithDuration:2.5 delay:0.0 options:UIViewAnimationOptionRepeat animations:^{
lineView.frame = CGRectMake(0, 200, 200, 1);
} completion:nil];
}
- (void)stopReading
{
// 停止
[_captureSession stopRunning];
[timer invalidate];
timer = nil;
_captureSession = nil;
}
-(void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects
fromConnection:(AVCaptureConnection *)connection
{
if (metadataObjects != nil && [metadataObjects count] > 0) {
AVMetadataMachineReadableCodeObject *metadataObj = [metadataObjects objectAtIndex:0];
NSString *result;
if ([[metadataObj type] isEqualToString:AVMetadataObjectTypeQRCode]) {
result = metadataObj.stringValue;
//扫描成功后的输出
} else {
//扫描失败后的输出
}
[self performSelectorOnMainThread:@selector(reportScanResult:) withObject:result waitUntilDone:NO];
}
}
//扫描的处理结果
- (void)reportScanResult:(NSString *)result
{
[self stopReading];
if (!_lastResult) {
return;
}
_lastResult = NO;
}
2 生成二维码
.h
#import <CoreImage/CoreImage.h>
@interface QRCodeViewController : UIViewController
//二维码的图片显示器
@property (weak, nonatomic) IBOutlet UIImageView *imageView;
- (void)createQRCode:(NSString *)imageUrl andImageSize:(CGFloat)imageSize;
@end
.m
#import "QRCodeViewController.h"
@interface QRCodeViewController ()
@end
@implementation QRCodeViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
}
- (void)createQRCode:(NSString *)imageUrl andImageSize:(CGFloat)imageSize
{
CIFilter * filter = [CIFilter filterWithName:@"CIQRCodeGenerator"];
[filter setDefaults];
//给过过滤器添加数据(正则表达式/账号和密码)
NSString * dataString = imageUrl;
NSData * data = [dataString dataUsingEncoding:NSUTF8StringEncoding];
[filter setValue:data forKeyPath:@"inputMessage"];
//获取输出的二维码
CIImage * outputImage = [filter outputImage];
//将CIImage转换成UIImage,放大显示
self.imageView.image = [self createNonInterpolatedUIImageFormCIImage:outputImage withSize:imageSize];
[self.view addSubview:self.imageView];
}
/**
* 根据CIImage生成指定大小的UIImage
*
* @param image CIImage
* @param size 图片宽度
*/
- (UIImage *)createNonInterpolatedUIImageFormCIImage:(CIImage *)image withSize:(CGFloat) size
{
CGRect extent = CGRectIntegral(image.extent);
CGFloat scale = MIN(size/CGRectGetWidth(extent),size/CGRectGetHeight(extent));
//创建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];
}
3.从本地读取二维码
系统原生的方法没有这项功能,需要用到第三方的,这里用ZXingObjC
#import "ZXingObjC.h"
@interface SaveQRCode : NSObject <UIImagePickerControllerDelegate,UINavigationControllerDelegate>
//将二维码保存到本地
//image 保存的图片名称
- (void) saveQRCodeToLocation:(UIImage *)image;
//从本地相册读取二维码
//vc : 用他的主视图
- (void) getQR:(UIViewController *)vc;
@end
.m
@interface SaveQRCode()
{
UIViewController * myViewController;
}
@end
@implementation SaveQRCode
- (void) saveQRCodeToLocation:(UIImage *)image
{
UIImageWriteToSavedPhotosAlbum(image, self, @selector(image:didFinishSavingWithError:contextInfo:), NULL);
}
- (void)image: (UIImage *) image didFinishSavingWithError: (NSError *) error contextInfo: (void *) contextInfo
{
NSString *msg = nil ;
if(error != NULL){
msg = @"保存图片失败" ;
}else{
msg = @"保存图片成功" ;
}
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"保存图片结果提示" message:msg delegate:self cancelButtonTitle:@"确定" otherButtonTitles:nil];
[alert show];
}
//从本地解析图片
- (void) getQR:(UIViewController *)vc
{
myViewController = vc;
[self pictureAction];
}
#pragma mark 照片处理
-(void)getInfoWithImage:(UIImage *)img{
//在这里添加观察者,pop到之前的界面传值
UIImage *loadImage= img;
CGImageRef imageToDecode = loadImage.CGImage;
ZXLuminanceSource *source = [[ZXCGImageLuminanceSource alloc] initWithCGImage:imageToDecode];
ZXBinaryBitmap *bitmap = [ZXBinaryBitmap binaryBitmapWithBinarizer:[ZXHybridBinarizer binarizerWithSource:source]];
NSError *error = nil;
ZXDecodeHints *hints = [ZXDecodeHints hints];
ZXMultiFormatReader *reader = [ZXMultiFormatReader reader];
ZXResult *result = [reader decode:bitmap
hints:hints
error:&error];
if (result) {
NSString *contents = result.text;
// [self showInfoWithMessage:contents andTitle:@"解析成功"];
NSLog(@"相册图片contents == %@",contents);
} else {
//[self showInfoWithMessage:nilandTitle:@"解析失败"];
}
}
#pragma mark ==相册
- (void)pictureAction
{
UIImagePickerControllerSourceType sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
if (![UIImagePickerController isSourceTypeAvailable: UIImagePickerControllerSourceTypePhotoLibrary]) {
sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
}
UIImagePickerController * picker = [[UIImagePickerController alloc]init];
picker.delegate = self;
picker.allowsEditing = YES;
picker.sourceType = sourceType;
[myViewController presentViewController:picker animated:YES completion:nil];
}
-(void)imagePickerControllerDIdCancel:(UIImagePickerController*)picker
{
[picker dismissViewControllerAnimated:YES completion:nil];
}
#pragma mark--从相册中选择图片
-(void)imagePickerController:(UIImagePickerController*)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
[picker dismissViewControllerAnimated:YES completion:nil];
UIImage * image = [info objectForKey:
UIImagePickerControllerEditedImage];
[self performSelector:@selector(selectPic:) withObject:image afterDelay:0.1];
}
- (void)selectPic:(UIImage*)image
{
//上传图片和昵称
if (image == nil) {
}else
{
[self getInfoWithImage:image];
}
}