? ? ? ?現(xiàn)在大多數(shù)的App都使用到二維碼钧大,所以就需要我們?cè)贏pp開發(fā)的時(shí)候畅形,加入這個(gè)功能阅懦。其實(shí)蘋果官方也提供了這樣的框架<CoreImage/CoreImage.h>,這個(gè)框架是需要手動(dòng)添加的
1. 導(dǎo)入庫(kù)后幌绍,我們就可以對(duì)象了
// 創(chuàng)建過(guò)濾對(duì)象?
CIQRCodeGenerator必須這樣寫? 才可以創(chuàng)建出來(lái)二維碼(意思就是我要?jiǎng)?chuàng)建的是二維碼修械,個(gè)人理解趾牧,英語(yǔ)水平有限)CIFilter *filter = [CIFilter filterWithName:@"CIQRCodeGenerator"];
2.這個(gè)對(duì)象是需要初始化后 ,要恢復(fù)下他的默認(rèn)設(shè)置 (也就一句代碼)
// 恢復(fù)默認(rèn)
[filter setDefaults];
3.這樣對(duì)象我們就可以設(shè)置好了 現(xiàn)在我們改設(shè)置下要生成的內(nèi)容了 (如果你設(shè)置的是個(gè)網(wǎng)址肯污,也不需要轉(zhuǎn)化為NSURL的翘单,直接設(shè)置為NSString就可以,可以自動(dòng)轉(zhuǎn)化的)
// 3.0 給過(guò)濾器添加數(shù)據(jù)? 如果想設(shè)置網(wǎng)址時(shí)? 直接將網(wǎng)址設(shè)置為NSString
//? ? NSString *dataString = @"小愛八點(diǎn)半";
NSString *dataString = @"http://www.baidu.com";
NSData *data =[dataString dataUsingEncoding:4];// 這個(gè)就是轉(zhuǎn)化為UFT-8
// 利用KVC將數(shù)據(jù)設(shè)置給過(guò)濾器? inputMessage也必須這樣寫
[filter setValue:data forKeyPath:@"inputMessage"];
在此的過(guò)濾對(duì)象設(shè)置些 ?二維碼的顏色
UIColor *onColor = [UIColor blackColor];// 繪制的顏色4.數(shù)據(jù)已經(jīng)設(shè)置好了蹦渣,也該生成最后的二維碼了? 圖片生成了哄芜,
UIColor *offColor = [UIColor whiteColor];// 空白的顏色
//上色
CIFilter *colorFilter = [CIFilter filterWithName:@"CIFalseColor" keysAndValues:@"inputImage",qrFilter.outputImage,@"inputColor0",[CIColor colorWithCGColor:onColor.CGColor],@"inputColor1",[CIColor colorWithCGColor:offColor.CGColor],nil];
// 獲取二維碼
CIImage * ciimage =[colorFilter outputImage];
5。但是該注意了柬唯,他是CIImage喲 ?其實(shí)也沒(méi)啥難度的认臊,也就是一句代碼就可以的
self.imageView.image = [UIImage imageWithCIImage:ciimage];
這樣我們的二維碼就能夠現(xiàn)實(shí)出來(lái)了锄奢,但是顯示出來(lái)不是很清楚的(這就是蘋果的坑爹之處)失晴,如果你們的策劃不是很嚴(yán)格的話,你就可以萬(wàn)事大吉拘央,此功能就完成涂屁。
下面再教大家一個(gè)個(gè)方法,生成個(gè)清晰的二維碼灰伟,其實(shí)就是拿著咱們的CIImage對(duì)象利用圖形上下文將圖形繪制一下
/**
*? 根據(jù)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));
// 1.創(chuàng)建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];
}
二維碼的掃描
1.二維碼的掃描就需要導(dǎo)入<AVFoundation/AVFoundation.h>框架?
// 創(chuàng)建撲捉對(duì)象? Capture Session? 捕獲會(huì)話
AVCaptureSession *session =[[AVCaptureSession alloc]init];
self.session = session;
2.創(chuàng)建輸入的設(shè)備 ?也就是掃描設(shè)備
// 2.0 設(shè)置輸入設(shè)備
/**
*? 創(chuàng)建輸入設(shè)備? 為攝像頭輸入 Video錄像
*/
AVCaptureDevice? *device =[AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
AVCaptureDeviceInput *input =[AVCaptureDeviceInput deviceInputWithDevice:device error:nil];
// 添加輸入設(shè)備
[session addInput:input];
3.0 設(shè)置輸出的方式 ?(也就是你要掃描什么樣的內(nèi)容)
// 3.0 設(shè)置輸出方式
AVCaptureMetadataOutput *outPut =[[AVCaptureMetadataOutput alloc]init];
// 添加輸入方式的代理方法 獲取掃描的數(shù)據(jù)? queue? 在哪個(gè)線程里面獲取掃描的對(duì)象
[outPut setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
[session addOutput:outPut];
/**
*? 設(shè)置掃描的是哪個(gè)數(shù)據(jù)? AVMetadataObjectTypeQRCode? 二維碼數(shù)據(jù)
*/
[outPut setMetadataObjectTypes:@[AVMetadataObjectTypeQRCode]];
4.0 創(chuàng)建個(gè)layer 就是掃描的區(qū)域
// 4.0? 添加一個(gè)顯示的layer
AVCaptureVideoPreviewLayer *layer =[[AVCaptureVideoPreviewLayer alloc]initWithSession:session];
// 掃描框在哪
layer.frame = self.view.bounds;
[self.view.layer addSublayer:layer];
self.layer = layer;
//? 5.0 開始掃描
[session startRunning];
5.0 最后就的在輸出內(nèi)容方式的代理方法里面截取到程序掃描的內(nèi)容
#pragma mark 代理的實(shí)現(xiàn)
-(void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection
{
if (metadataObjects.count > 0) {
// 1.0 獲取數(shù)據(jù)
AVMetadataMachineReadableCodeObject *object =[metadataObjects lastObject];
NSLog(@"%@",object.stringValue);// 如果獲取的是個(gè)網(wǎng)址拆又,直接會(huì)跳轉(zhuǎn)到網(wǎng)址的地址頁(yè)面
//2.0 停止掃描
[self.session stopRunning];
// 3.0 移除掃描圖層
[self.layer removeFromSuperlayer];
}
}