// // main.swift // OCRImage // // Created on 04/03/2021. // import Foundation import ArgumentParser import Vision import AppKit class TextPiece { var text:String?; var topLeft:CGPoint; var topRight:CGPoint; var bottomLeft:CGPoint; var bottomRIght:CGPoint; init() { self.text = "Empty"; self.topLeft = CGPoint(x:0,y:0); self.topRight = CGPoint(x:0,y:0); self.bottomLeft = CGPoint(x:0,y:0); self.bottomRIght = CGPoint(x:0,y:0); } init(_ t: String, _ tl:CGPoint, _ tr:CGPoint, _ bl:CGPoint, _ br: CGPoint ) { self.text = t; self.topLeft = tl; self.topRight = tr; self.bottomLeft = bl; self.bottomRIght = br; } func set(_ t: String, _ tl:CGPoint, _ tr:CGPoint, _ bl:CGPoint, _ br: CGPoint) { self.text = t; self.topLeft = tl; self.topRight = tr; self.bottomLeft = bl; self.bottomRIght = br; } } class TextOCR { var pieces:[TextPiece] = [] init() { } func recognizeImageUrl(_ url:URL, _ error: Error?) { var pieces:[TextPiece] = [] var err:NSError? var textRequest = VNRecognizeTextRequest(completionHandler: recognizeTextHandler(request:error:)) var handler = VNImageRequestHandler(url: url) do { try handler.perform([textRequest]) } catch { print("Cannot perfom request error:\(error)") } } func handleTextRequest(_ request: VNRequest, error: Error?) { } func recognizeTextHandler(request: VNRequest, error: Error?) { print("Start recognize handler") guard let observations = request.results as? [VNRecognizedTextObservation] else { return } let recognizedStrings = observations.compactMap { observation in // Return the string of the top VNRecognizedText instance. return observation.topCandidates(1).first?.string } print("\(recognizedStrings)") } } print("Start program") let stderr = FileHandle.standardError if #available(macOS 10.15,*) {} else { //Output to stderr if os version is not supported stderr.write("Version of MacOS should be >=10.15".data(using: .utf8)!) exit(0) } struct OCROptions : ParsableArguments { @Option(help:"Input file for OCR") var inputFile:String? @Flag(name: .shortAndLong, help:"Show extra debugion info") var debug=false @Flag(name:.shortAndLong, help:"Show current version") var version=false } let options = OCROptions.parseOrExit() //Print version version and quit if options.version { print("Version: 0.0.2") exit(0) } guard let inputFile = options.inputFile else { print("ERROR: Set --input-file command argument to image") exit(0) } if options.debug { print("OCR Input file: \(inputFile)") } //return true if file excists func checkIfFileExists(_ fname: String) -> Bool { let fm = FileManager.default if fm.fileExists(atPath: fname) { return true } return false } //get current run directory func getCurrentExecutableDir() -> String { return Process().currentDirectoryPath } var executionPath = getCurrentExecutableDir() var fm_full_path = FileManager.default fm_full_path.changeCurrentDirectoryPath(executionPath) var inputURL = URL(fileURLWithPath: fm_full_path.currentDirectoryPath) inputURL.appendPathComponent(inputFile) var composePath = "/"+inputURL.pathComponents.filter { ($0 != ".") && ($0 != "/") }.joined(separator: "/") if (options.debug) { print(composePath) print(checkIfFileExists(composePath)) print(getCurrentExecutableDir()) print(executionPath) } //load image var composeUrl:URL? = nil if checkIfFileExists(composePath) { composeUrl = URL(fileURLWithPath: composePath) } else if checkIfFileExists(inputFile) { composeUrl = URL(fileURLWithPath: inputFile) } else { print("Canot open file path \(inputFile)") exit(0) } let image = NSImage(contentsOf: composeUrl!) if (image == nil) { stderr.write("Cannot load image properly \(composeUrl!)".data(using: .utf8)!) exit(0) } //Start text recognition request var ocr = TextOCR() var err:NSError? ocr.recognizeImageUrl(composeUrl!, err) print("End programm")