투케이2K

195. (Objective-C/objc) IOS import Vision 사용해 QR 및 Barcode 이미지 파일 (png, jpg) 스캔 수행 본문

Objective-C

195. (Objective-C/objc) IOS import Vision 사용해 QR 및 Barcode 이미지 파일 (png, jpg) 스캔 수행

투케이2K 2026. 1. 2. 19:42
728x90

[개발 환경 설정]

개발 툴 : XCODE

개발 언어 : OBJECTIVE-C

 

[소스 코드]

// --------------------------------------------------------------------------------------
[개발 및 테스트 환경]
// --------------------------------------------------------------------------------------

- 언어 : Objective-c


- 개발 툴 : Xcode


- 기술 구분 : Vision / QR / Barcode


- 사전) VNDetectBarcodesRequest 간단 설명 및 사용 범위 : 

  >> Apple 공식 / 안정적

  >> import Vision 만 하면 바로 사용 가능

  >> QR 코드 디코딩 가능

  >> 1D / 2D 바코드 디코딩 가능

  >> 이미지 파일 디코딩 가능


- 사전) QR 및 바코드가 인식되지 않는 경우 정리 : 

  >> 이미지 가로 해상도 부족 (CODE 128은 600px 이상 권장)

  >> 바코드 좌우 여백 부족

  >> PNG 투명 배경

// --------------------------------------------------------------------------------------






// --------------------------------------------------------------------------------------
[소스 코드]
// --------------------------------------------------------------------------------------

// -------------------------------------------------------------------
// MARK: [QR 및 Barcode 저장 된 이미지 스캔 메소드]
// -------------------------------------------------------------------
// [필요 import]
// -------------------------------------------------------------------
// #import <Vision/Vision.h>
// #import <UIKit/UIKit.h>
// -------------------------------------------------------------------

- (void)getQrBarcodeImageFileScan:(UIImage *)image
                       completion:(void (^)(NSString *result))completion {

    dispatch_async(dispatch_get_main_queue(), ^{
        NSLog(@"QR 및 Barcode 저장 된 이미지 스캔 수행");

        if (!image) {
            NSLog(@"[Error] UIImage Is Nil");
            completion(@"");
            return;
        }

        // ✅ PNG 투명 알파 제거 (Swift UIGraphicsImageRenderer 대응)
        UIGraphicsBeginImageContextWithOptions(image.size, YES, image.scale);
        [[UIColor whiteColor] setFill];
        UIRectFill(CGRectMake(0, 0, image.size.width, image.size.height));
        [image drawAtPoint:CGPointZero];
        UIImage *processedImage = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();

        CGImageRef cgImage = processedImage.CGImage;
        if (!cgImage) {
            NSLog(@"[Error] CGImage 변환 실패");
            completion(@"");
            return;
        }

        __block NSString *returnData = @"";

        // ✅ VNDetectBarcodesRequest 생성
        VNDetectBarcodesRequest *request =
        [[VNDetectBarcodesRequest alloc] initWithCompletionHandler:^(VNRequest * _Nonnull request, NSError * _Nullable error) {

            if (error) {
                NSLog(@"[Error] Vision - %@", error.localizedDescription);
                completion(@"");
                return;
            }

            NSArray<VNBarcodeObservation *> *results =
            (NSArray<VNBarcodeObservation *> *)request.results;

            if (results.count == 0) {
                NSLog(@"[Error] Vision - Result Not Found");
                completion(@"");
                return;
            }

            for (VNBarcodeObservation *barcode in results) {
                NSLog(@"Vision 심볼 : %@", barcode.symbology);
                NSLog(@"Vision 값 : %@", barcode.payloadStringValue);

                if (barcode.payloadStringValue.length > 0) {
                    returnData = barcode.payloadStringValue;
                }
            }

            if (returnData.length > 0) {
                NSLog(@"QR 및 Barcode 저장 된 이미지 스캔 성공 : %@", returnData);
                completion(returnData);
            } else {
                NSLog(@"[Error] Vision - Search Data Not Found");
                completion(@"");
            }
        }];

        // 🔑 QR + Barcode 동시 허용
        request.symbologies = @[
            VNBarcodeSymbologyQR,
            VNBarcodeSymbologyEAN13,
            VNBarcodeSymbologyEAN8,
            VNBarcodeSymbologyUPCE,
            VNBarcodeSymbologyCode128,
            VNBarcodeSymbologyCode39,
            VNBarcodeSymbologyCode93,
            VNBarcodeSymbologyPDF417,
            VNBarcodeSymbologyDataMatrix,
            VNBarcodeSymbologyAztec
        ];

        // 안정성 옵션 (선택)
        // request.usesCPUOnly = YES;

        // Vision 핸들러 생성
        VNImageRequestHandler *handler =
        [[VNImageRequestHandler alloc] initWithCGImage:cgImage
                                               options:@{}];

        NSError *visionError = nil;
        [handler performRequests:@[request] error:&visionError];

        if (visionError) {
            NSLog(@"[Exception] Vision - %@", visionError.localizedDescription);
            completion(@"");
        }
    });
}

// --------------------------------------------------------------------------------------





// --------------------------------------------------------------------------------------
[참고 사이트]
// --------------------------------------------------------------------------------------

[라이브러리] [Ios] QRCodeReader (Swift / Camera / QR)

https://blog.naver.com/kkh0977/222915053266?trackingCode=blog_bloghome_searchlist


[라이브러리] [Ios] QRCode (Swift / Camera / QR)

https://blog.naver.com/kkh0977/222915071986?trackingCode=blog_bloghome_searchlist


[Mobile] 모바일 ( android , ios ) 에서 QR 코드 생성 시 화면 밝기 및 QR 코드 사이즈 최대 표시 Alert 팝업창 활성

https://blog.naver.com/kkh0977/223624876714?trackingCode=blog_bloghome_searchlist


[Mobile] 모바일 ( android , ios ) 에서 QR 코드 스캔 후 정보 확인 및 다시 스캔 로직 수행

https://blog.naver.com/kkh0977/223624907452?trackingCode=blog_bloghome_searchlist

// --------------------------------------------------------------------------------------
 
728x90
반응형
Comments