[swift] RxSwift를 이용한 OCR 처리 방법

이 문서에서는 RxSwift를 사용하여 OCR (Optical Character Recognition) 처리를 하는 방법을 알아보겠습니다. OCR은 이미지나 스캔된 문서에서 텍스트를 인식하는 기술로 많은 분야에서 유용하게 사용됩니다. RxSwift는 비동기 프로그래밍을 간편하게 처리하기 위한 리액티브 프로그래밍 라이브러리로 유명합니다.

필요한 라이브러리 설치

이 예제에서는 RxSwift와 RxCocoa를 사용하므로, 프로젝트에 이 두 라이브러리를 설치해야합니다.

# Podfile

platform :ios, '13.0'

target 'YourProjectName' do
  use_frameworks!

  pod 'RxSwift', '~> 5'
  pod 'RxCocoa', '~> 5'
end

터미널에서 pod install 명령을 실행하여 라이브러리를 설치할 수 있습니다.

OCR 처리를 위한 RxSwift 사용하기

  1. UIImagePickerController를 이용하여 이미지를 선택합니다.
import UIKit
import RxSwift
import RxCocoa

class ViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
    private let disposeBag = DisposeBag()

    private let imagePicker = UIImagePickerController()

    override func viewDidLoad() {
        super.viewDidLoad()

        imagePicker.delegate = self

        let selectImageBarButtonItem = UIBarButtonItem(title: "Select Image", style: .plain, target: self, action: #selector(selectImage))

        navigationItem.rightBarButtonItem = selectImageBarButtonItem
    }

    @objc private func selectImage() {
        imagePicker.sourceType = .photoLibrary
        present(imagePicker, animated: true, completion: nil)
    }

    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
        picker.dismiss(animated: true, completion: nil)

        guard let pickedImage = info[.originalImage] as? UIImage else {
            return
        }

        processImage(pickedImage)
    }

    private func processImage(_ image: UIImage) {
        // OCR 처리 로직을 구현합니다.
    }
}
  1. processImage() 메서드에서 OCR 처리를 구현합니다. 이때 RxSwift의 Observable을 사용하여 비동기 처리를 할 수 있습니다.
import Vision
import RxSwift

private func processImage(_ image: UIImage) {
    guard let ciImage = CIImage(image: image) else {
        return
    }

    let ocrObservable = Observable.create { observer in
        let requestHandler = VNImageRequestHandler(ciImage: ciImage)
        let textRecognitionRequest = VNRecognizeTextRequest { request, error in
            if let error = error {
                observer.onError(error)
                return
            }

            guard let observations = request.results as? [VNRecognizedTextObservation] else {
                observer.onError(OCRProcessingError.invalidResult)
                return
            }

            let recognizedText = observations.compactMap { observation in
                observation.topCandidates(1).first?.string
            }.joined(separator: " ")

            observer.onNext(recognizedText)
            observer.onCompleted()
        }

        do {
            try requestHandler.perform([textRecognitionRequest])
        } catch {
            observer.onError(error)
        }

        return Disposables.create()
    }

    ocrObservable.subscribe(onNext: { recognizedText in
        // 결과 처리 로직을 구현합니다.
    }, onError: { error in
        // 에러 처리 로직을 구현합니다.
    }).disposed(by: disposeBag)
}

위의 코드에서 VNRecognizeTextRequest는 Vision 프레임워크를 사용하여 OCR을 처리하는데 사용되는 클래스입니다. OCR 결과는 VNRecognizedTextObservation 객체에서 추출되며, 이를 통해 인식된 텍스트를 가져올 수 있습니다.

  1. OCR 처리 결과를 처리하는 부분에 대한 로직을 추가합니다.
ocrObservable.subscribe(onNext: { recognizedText in
    DispatchQueue.main.async {
        // 인식된 텍스트를 UI에 표시하거나 추가로 처리하는 로직을 구현합니다.
    }
}, onError: { error in
    DispatchQueue.main.async {
        // 에러 처리 로직을 구현합니다.
    }
}).disposed(by: disposeBag)

여기까지 RxSwift를 이용한 OCR 처리 방법에 대해 알아보았습니다. 이제 앱에서 이미지를 선택하고 OCR로 텍스트를 추출하는 기능을 구현할 수 있습니다.

결론

RxSwift는 비동기 프로그래밍을 간결하게 처리하기 위한 강력한 도구입니다. OCR과 같이 복잡한 비동기 작업을 처리할 때 RxSwift의 사용은 코드의 가독성과 유지보수성을 향상시키는데 도움이 됩니다.