From ae67804cb8ab158ec0a37db706cb162061ae0882 Mon Sep 17 00:00:00 2001 From: Martin Braun Date: Sun, 31 Dec 2023 06:18:53 +0100 Subject: [PATCH] allow unattended silent screenshot of given rect --- README.md | 3 ++- Sources/ocr/CLIArgs.swift | 4 +++- Sources/ocr/OCRApp.swift | 15 +++++++++------ Sources/ocr/ScreenCapture.swift | 4 ++-- 4 files changed, 16 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 305a3ab..6a0be60 100644 --- a/README.md +++ b/README.md @@ -13,10 +13,11 @@ Takes file, stdin, or screencapture as input. > cd macOCR > swift build -c release > .build/release/ocr -h -USAGE: ocr [--capture] [--stdin] [-i ] +USAGE: ocr [--capture] [-r ] [--stdin] [-i ] OPTIONS: -c, --capture Capture screenshot. + -r Rectangle to unattendedly capture (-r x,y,w,h), needs --capture. -s, --stdin Read stdin binary data. -i Path to input image. -h, --help Show help information. diff --git a/Sources/ocr/CLIArgs.swift b/Sources/ocr/CLIArgs.swift index 4fc329d..f55fd3a 100644 --- a/Sources/ocr/CLIArgs.swift +++ b/Sources/ocr/CLIArgs.swift @@ -7,12 +7,14 @@ struct CLIArgs { @Flag(name: [.customShort("c"), .long], help: "Capture screenshot.") var capture: Bool = false + @Option(name: [.customShort("r")], help: "Rectangle to unattendedly capture (-r x,y,w,h), needs --capture.") + var rectangle: String? + @Flag(name: [.customShort("s"), .long], help: "Read stdin binary data.") var stdin: Bool = false @Option(name: [.customShort("i")], help: "Path to input image.", completion: CompletionKind.file(extensions: ["gif", "png", "jpg", "webp", "tiff"])) var input: String? - } } diff --git a/Sources/ocr/OCRApp.swift b/Sources/ocr/OCRApp.swift index 701f977..368c374 100644 --- a/Sources/ocr/OCRApp.swift +++ b/Sources/ocr/OCRApp.swift @@ -14,14 +14,18 @@ class OCRApp { func run() { let args = CLIArgs.ocr.parseOrExit() let image: CGImage? - switch (args.input, args.stdin, args.capture) { - case (.some(let path), false, false): + switch (args.input, args.stdin, args.capture, args.rectangle) { + case (.some(let path), false, false, .none): image = imageFromURL(path.pathAsURL) - case (.none, true, false): + case (.none, true, false, .none): image = imageFromStdIn() - case (.none, false, true): + case (.none, false, true, .some(let rect)): let tempURL = URL(fileURLWithPath: "/tmp/ocr-\(UUID().uuidString).png") - image = imageFromURL(captureRegion(destination: tempURL)) + image = imageFromURL(captureRegion(destination: tempURL, rect: rect)) + try? FileManager.default.removeItem(at: tempURL) + case (.none, false, true, .none): + let tempURL = URL(fileURLWithPath: "/tmp/ocr-\(UUID().uuidString).png") + image = imageFromURL(captureRegion(destination: tempURL, rect: nil)) try? FileManager.default.removeItem(at: tempURL) default: CLIArgs.ocr.exit(withError: ArgumentParser.ValidationError("Input not properly specified.")) @@ -86,7 +90,6 @@ class OCRApp { return image.cgImage(forProposedRect: &imageRect, context: nil, hints: nil) } - func imageFromURL(_ inputURL: URL) -> CGImage? { if let ciImage = CIImage(contentsOf: inputURL), let cgImage = CIContext(options: nil) diff --git a/Sources/ocr/ScreenCapture.swift b/Sources/ocr/ScreenCapture.swift index 65da3b5..cdca913 100644 --- a/Sources/ocr/ScreenCapture.swift +++ b/Sources/ocr/ScreenCapture.swift @@ -1,11 +1,11 @@ import Foundation -func captureRegion(destination: URL) -> URL { +func captureRegion(destination: URL, rect: String?) -> URL { let destinationPath = destination.path as String let task = Process() task.launchPath = "/usr/sbin/screencapture" - task.arguments = ["-i", "-r", destinationPath] + task.arguments = rect != nil ? ["-R" + rect!, "-x", "-r", destinationPath] : ["-i", "-r", destinationPath] task.launch() task.waitUntilExit()