DirTy™의 하루일과/DirTy™의 가당찮은iOS

[IOS] qr code reader, generator

DirTy™ 2015. 1. 16. 09:58

ios앱 구현할때 자주 사용은 안하겠지만...

프로젝트중에 qr code 생성 및 읽기 기능이 필요하여 구글신의 도움을 받아 구현하였다.


qr code reader


- (void)viewDidLoad

{

    [super viewDidLoad];


 // qrcode 읽을때 사용할 카메라 세션 설정 

    [self AVFoundationQRViewInitCamera];

}


// 카메라 세션을 설정하고 카메라를 실행 시킨다.

- (void)AVFoundationQRViewInitCamera {

    _session = [[AVCaptureSession alloc] init];

    AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];

    if(device != nil) {

        NSError *error = nil;

        

        _previewLayer = [AVCaptureVideoPreviewLayer layerWithSession:_session];

        

        // Display full screen(사이즈는 개인 사용자에 맞게 맞추면 된다.)

        _previewLayer.frame = CGRectMake(0, self.navigationController.navigationBar.frame.size.height + 30.0f, self.view.frame.size.width, (self.view.frame.size.height - (self.navigationController.navigationBar.frame.size.height + 70.0f)));

        

        // Add the video preview layer to the view

        [self.view.layer addSublayer:_previewLayer];

        

        AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:device

                                                                            error:&error];

        if (input) {

            [_session addInput:input];

        } else {

            NSLog(@"Error: %@", error);

        }

        

        AVCaptureMetadataOutput *output = [[AVCaptureMetadataOutput alloc] init];

        [output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];

        

        [_session addOutput:output];

        output.metadataObjectTypes = @[AVMetadataObjectTypeQRCode];

        

 // 카메라 세션을 시작한다.

        [_session startRunning];

    }

}


// qrcode 읽은 값은 아래의 메서드로 들어온다.

- (void)captureOutput:(AVCaptureOutput *)captureOutput

didOutputMetadataObjects:(NSArray *)metadataObjects

       fromConnection:(AVCaptureConnection *)connection

{   

    for (AVMetadataObject *metadata in metadataObjects) {

        if ([metadata.type isEqualToString:AVMetadataObjectTypeQRCode]) {

            

            QRCode = [(AVMetadataMachineReadableCodeObject *)metadata stringValue];

            break;

        }

    }

    

    NSLog(@"QR Code: %@", QRCode);

    

    [_session stopRunning];

    [_previewLayer removeFromSuperlayer];

    _previewLayer = nil;

    _session = nil;

}


qr code generator

일단 아래와같이 storyboard의 viewcontroller에 UIImageView를 하나 만들고 property를 연결해두자.

난 아래와같이 property를 설정하였다.

@property (strong, nonatomic) IBOutlet UIImageView *qrimg;




그리고 아래와 같이 viewcontroller에 구현하여 보자.(ctrl+c, ctrl+v)


- (void)createQRID:(NSString *)qrID {

    CIImage *img = [self createQRForString:qrID];

    

    self.qrimg.image = [self createNonInterpolatedUIImageFromCIImage:img withScale:5.0f];

    [self timerstart];

}


- (CIImage *)createQRForString:(NSString *)qrString

{

    // Need to convert the string to a UTF-8 encoded NSData object

    NSData *stringData = [qrString dataUsingEncoding:NSUTF8StringEncoding];

    

    // Create the filter

    CIFilter *qrFilter = [CIFilter filterWithName:@"CIQRCodeGenerator"];

    // Set the message content and error-correction level

    [qrFilter setValue:stringData forKey:@"inputMessage"];

    [qrFilter setValue:@"H" forKey:@"inputCorrectionLevel"];

    

    // Send the image back

    return qrFilter.outputImage;

}


- (UIImage *)createNonInterpolatedUIImageFromCIImage:(CIImage *)image withScale:(CGFloat)scale

{

    // Render the CIImage into a CGImage

    CGImageRef cgImage = [[CIContext contextWithOptions:nil] createCGImage:image fromRect:image.extent];

    

    // Now we'll rescale using CoreGraphics

    UIGraphicsBeginImageContext(CGSizeMake(image.extent.size.width * scale, image.extent.size.width * scale));

    CGContextRef context = UIGraphicsGetCurrentContext();

    // We don't want to interpolate (since we've got a pixel-correct image)

    CGContextSetInterpolationQuality(context, kCGInterpolationNone);

    CGContextDrawImage(context, CGContextGetClipBoundingBox(context), cgImage);

    // Get the image out

    UIImage *scaledImage = UIGraphicsGetImageFromCurrentImageContext();

    if(DEBUG) {

        NSLog(@"scaledImage.width : %f   scaledImage.height : %f", scaledImage.size.width, scaledImage.size.height);

    }

    // Tidy up

    UIGraphicsEndImageContext();

    CGImageRelease(cgImage);

    return scaledImage;

}


실행하여 보면 결과는 이런식으로 나온다.





}