2// Get OCR'd text from an image using Live Text in macOS.
4// If you're using Preview, you can use Live Text to copy and paste text
5// that's in an image. This script allows you to access that text
6// programatically, which is useful if you want to do bulk analysis of
7// the text in your images.
9// You can search text in the Photos app, but this is useful if you:
11// - want to search images that aren't in your Photos library
12// - want to do analysis which isn't just searching
14// This is based on https://developer.apple.com/documentation/vision/recognizing_text_in_images
16// Tested on macOS Monterey.
18// You may need to run `chmod +x get_live_text` first and install the Xcode
23// Pass the path to your image as a single command-line argument. Any text
24// in the image will be returned as a JSON list:
26// $ get_live_text railway-sign.jpg
27// ["Passengers must","not pass this point","or cross the line"]
29// If the image doesn't contain any text, it returns an empty list:
31// $ get_live_text dancers.jpg
37let SCRIPT_VERSION = "1.0.0"
39// Process the results of the text-recognition request.
41// This is based on the code in Apple's documentation, and prints the
42// recognized text as a list of JSON strings.
44// See https://developer.apple.com/documentation/vision/recognizing_text_in_images#3601255
45func recognizeTextHandler(request: VNRequest, error: Error?) {
48 request.results as? [VNRecognizedTextObservation]
52 let recognizedStrings = observations.compactMap { observation in
53 // Return the string of the top VNRecognizedText instance.
54 return observation.topCandidates(1).first?.string
57 print(recognizedStrings.joined(separator: " "))
60// Given the path to an image, print a JSON array of text it contains.
61func printTextInImage(imagePath: String) {
62 if !FileManager.default.fileExists(atPath: imagePath) {
63 fputs("Cannot find file at path: \(imagePath)\n", stderr)
67 let requestHandler = VNImageRequestHandler(
68 url: URL(fileURLWithPath: imagePath),
72 let request = VNRecognizeTextRequest(completionHandler: recognizeTextHandler)
75 // Perform the text-recognition request.
76 try requestHandler.perform([request])
78 fputs("Unable to recognise text: \(error).\n", stderr)
83let arguments = CommandLine.arguments
85if arguments.count == 2 && arguments[1] == "--version" {
86 let filename = (arguments[0] as NSString).lastPathComponent
87 print("\(filename) \(SCRIPT_VERSION)")
91if arguments.count != 2 {
92 fputs("Usage: \(arguments[0]) <PATH>\n", stderr)
96printTextInImage(imagePath: arguments[1])