1:搭建扫描环境:扫描框、扫描线、相册按钮等等。
//设置定时器
_timer = [NSTimer scheduledTimerWithTimeInterval:1.2 target:self selector:@selector(animationAction) userInfo:nil repeats:YES];
- (void)animationAction
{
[UIView animateWithDuration:时间 animations:^{
_line.frame = CGRectMake(起始扫描位置);
}completion:^(BOOL finished) {
[UIView animateWithDuration:时间 animations:^{ _line.frame = CGRectMake(扫描终点位置)
}]; }];
}
2:判断是否支持相机
`if([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera])`
3:初始化相机(可在viewDidLoad中调用)进行拍摄
self.capSession = [[AVCaptureSession alloc] init];
AVCaptureDevice *inputDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
AVCaptureDeviceInput *captureInput = [AVCaptureDeviceInput deviceInputWithDevice:inputDevice error:nil];
[self.capSession addInput:captureInput];
AVCaptureVideoDataOutput *captureOutput = [[AVCaptureVideoDataOutput alloc] init];
captureOutput.alwaysDiscardsLateVideoFrames = YES;
//判断版本
//iOS7执行如下
if ([[[UIDevice currentDevice] systemVersion]floatValue] >= 7) {
AVCaptureMetadataOutput *metadata = [[AVCaptureMetadataOutput alloc]init];
[metadata setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
[self.capSession setSessionPreset:AVCaptureSessionPresetHigh];
[self.capSession addOutput:metadata];
metadata.metadataObjectTypes = @[AVMetadataObjectTypeQRCode];
if (!self.captureVideoPreviewLayer) {
self.captureVideoPreviewLayer = [AVCaptureVideoPreviewLayer layerWithSession:self.capSession];
}
self.captureVideoPreviewLayer.frame = self.view.bounds;
self.captureVideoPreviewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
[self.view.layer addSublayer: self.captureVideoPreviewLayer];
[self.capSession startRunning];}
//不是iOS7的话 如下:
else{
[captureOutput setSampleBufferDelegate:self queue:dispatch_get_main_queue()];
NSString* key = (NSString *)kCVPixelBufferPixelFormatTypeKey;
NSNumber* value = [NSNumber numberWithUnsignedInt:kCVPixelFormatType_32BGRA];
NSDictionary *videoSettings = [NSDictionary dictionaryWithObject:value forKey:key];
[captureOutput setVideoSettings:videoSettings];
[self.capSession addOutput:captureOutput];
NSString* preset = 0;
if (NSClassFromString(@"NSOrderedSet") &&
[UIScreen mainScreen].scale > 1 &&
[inputDevice supportsAVCaptureSessionPreset:AVCaptureSessionPresetiFrame960x540]) {
// NSLog(@"960");
preset = AVCaptureSessionPresetiFrame960x540;
}
if (!preset) {
// NSLog(@"MED");
preset = AVCaptureSessionPresetMedium;
}
self.capSession.sessionPreset = preset;
if (!self.captureVideoPreviewLayer) {
self.captureVideoPreviewLayer = [AVCaptureVideoPreviewLayer layerWithSession:self.capSession];
}
// NSLog(@"prev %p %@", self.prevLayer, self.prevLayer);
self.captureVideoPreviewLayer.frame = self.view.bounds;
self.captureVideoPreviewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
[self.view.layer addSublayer: self.captureVideoPreviewLayer];
self.isScaning = YES;
[self.capSession startRunning];}
//OK之后 在这里实现相机的代理方法
//iOS7如下
- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection
{
if (metadataObjects.count>0)
{
AVMetadataMachineReadableCodeObject * metadataObject = [metadataObjects objectAtIndex:0];
//result就是扫描结果的string信息
self.ScanResult(metadataObject.stringValue,YES);
_result = metadataObject.stringValue;
}
[self.capSession stopRunning];
//如若需要改变扫描位置,可在此执行
[self dismissViewControllerAnimated:YES completion:nil];}
//iOS7之前
- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection
{
//获取图片信息,方法下文会阐明
UIImage *image = [self imageFromSampleBuffer:sampleBuffer];
//解码图片
[self decodeImage:image];
}
4:非iOS7中利用获取图片如下 <为大神所作>
- (UIImage *) imageFromSampleBuffer:(CMSampleBufferRef) sampleBuffer
{
CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);
// Lock the base address of the pixel buffer
CVPixelBufferLockBaseAddress(imageBuffer,0);
// Get the number of bytes per row for the pixel buffer
size_t bytesPerRow = CVPixelBufferGetBytesPerRow(imageBuffer);
// Get the pixel buffer width and height
size_t width = CVPixelBufferGetWidth(imageBuffer);
size_t height = CVPixelBufferGetHeight(imageBuffer);
// Create a device-dependent RGB color space
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
if (!colorSpace)
{
NSLog(@"CGColorSpaceCreateDeviceRGB failure");
return nil;
}
// Get the base address of the pixel buffer
void *baseAddress = CVPixelBufferGetBaseAddress(imageBuffer);
// Get the data size for contiguous planes of the pixel buffer.
size_t bufferSize = CVPixelBufferGetDataSize(imageBuffer);
// Create a Quartz direct-access data provider that uses data we supply
CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, baseAddress, bufferSize,
NULL);
// Create a bitmap image from data supplied by our data provider
CGImageRef cgImage =
CGImageCreate(width,
height,
8,
32,
bytesPerRow,
colorSpace,
kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Little,
provider,
NULL,
true,
kCGRenderingIntentDefault);
CGDataProviderRelease(provider);
CGColorSpaceRelease(colorSpace);
// Create and return an image object representing the specified Quartz image
UIImage *image = [UIImage imageWithCGImage:cgImage];
return image;
}
5:非iOS7下 或是 自行选取图片,需要解码图片,这里可以使用ZBar第三方,导入之库之后,如下:
- (void)decodeImage:(UIImage *)image
{
ZBarSymbol *symbol = nil;
ZBarReaderController* read = [ZBarReaderController new];
read.readerDelegate = self;
//获取信息
CGImageRef cgImageRef = image.CGImage;
//遍历
for(symbol in [read scanImage:cgImageRef])break;
//如果解析到数据
if (symbol != nil) {
//编码方式
if ([symbol.data canBeConvertedToEncoding:NSShiftJISStringEncoding]) {
// self.scanResult([NSString stringWithCString:[symbol.data cStringUsingEncoding:NSShiftJISStringEncoding] encoding:NSUTF8StringEncoding],YES);
_result = [NSString stringWithCString:[symbol.data cStringUsingEncoding:NSShiftJISStringEncoding] encoding:NSUTF8StringEncoding];
}else{
_result = symbol.data;
}
[self.capSession stopRunning];
[self dismissViewControllerAnimated:YES completion:nil];//跳转你需要的界面即可
}else{
//没有解析到数据就要执行扫描
_timer = [NSTimer scheduledTimerWithTimeInterval:1.2 target:self selector:@selector(animationAction) userInfo:nil repeats:YES];
//如果需要改变扫描线位置可在此执行
[self.capSession startRunning];
}
}
6:相册选取解码:
//判断是否支持相册功能
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary]) {
UIImagePickerController *picker = [[UIImagePickerController alloc] init];
picker.allowsEditing = YES;
picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
picker.delegate = self;
[self presentViewController:picker animated:YES completion:^{
[self.capSession stopRunning];
}];
}else{
//这里我是写了一个宏命令,省去垃圾代码
Show_AlterView(@"不支持系统相册");
}
//实现代理
//点击取消按钮 代码仅供参考
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker
{
[self dismissViewControllerAnimated:YES completion:nil];
_timer = [NSTimer scheduledTimerWithTimeInterval:1.2 target:self selector:@selector(animationAction) userInfo:nil repeats:YES];
[self.capSession startRunning];
}
//选取图片的时候解码图片
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
UIImage *image = [info objectForKey:@"UIImagePickerControllerEditedImage"];
[self dismissViewControllerAnimated:YES completion:^{
[self decodeImage:image];//选取之后解码图片
}];
}
7:打开手电筒
//如果有需要的话,可以添加,配置硬件 lock,unlock是必须的
[_capLightDevice lockForConfiguration:nil];
[_capLightDevice setTorchMode:AVCaptureTorchModeOn];
[_capLightDevice unlockForConfiguration];
8:生成二维码
1. 导入头文件#import “QRCodeGenerator.h”
2. 编码内容成二维码
- (void)createImage
{
UIImage *image = [QRCodeGenerator qrImageForString:@"要生成的内容" imageSize:200.0];
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(二维码的图片大小)];
imageView.backgroundColor = [UIColor orangeColor];
imageView.image = image;
[self.view addSubview:imageView];