Skip to content

Instantly share code, notes, and snippets.

@jvarn
Last active March 11, 2025 04:31
Show Gist options
  • Save jvarn/99ab63638bf07f0bbaff061221e66af8 to your computer and use it in GitHub Desktop.
Save jvarn/99ab63638bf07f0bbaff061221e66af8 to your computer and use it in GitHub Desktop.
These AppleScripts use the "Live Text" OCR feature available in Preview in recent versions of macOS to extract text from single or multiple images. One version runs from the command line, while the other version is for Finder Quick Action integration using Automator. Adapted from: https://stackoverflow.com/questions/71104893/macos-how-to-access-…
-- Automator version
-- usage:
-- 1. Create new Quick Action in macOS Automator
-- 2. Workflow receives current "image files" in "Finder"
-- 3. Add "Run Applescript"
-- 4. Paste this code
-- 5. Now you can right-click on an image or multiple images in Finder to extract the text to .txt files.
use framework "Vision"
use framework "Foundation"
use scripting additions -- For file operations
on run {input, parameters}
set batchSize to 100 -- Set the batch size for processing
set totalFiles to (count input)
repeat with i from 1 to totalFiles by batchSize
-- Determine the end index for the current batch
set endIndex to (i + batchSize - 1)
if endIndex > totalFiles then
set endIndex to totalFiles
end if
-- Process the current batch of files
repeat with j from i to endIndex
-- Get the image file path
set imagePath to POSIX path of (item j of input)
-- Get image content
set fileURL to current application's NSURL's fileURLWithPath:imagePath
set theImage to current application's NSImage's alloc()'s initWithContentsOfURL:fileURL
if theImage is missing value then
error "Image could not be loaded: " & imagePath
end if
-- Set up request handler using image's raw data
set imageData to theImage's TIFFRepresentation()
if imageData is missing value then
error "Failed to extract TIFF representation from: " & imagePath
end if
set requestHandler to current application's VNImageRequestHandler's alloc()'s initWithData:imageData options:(current application's NSDictionary's alloc()'s init())
-- Initialize text request
set theRequest to current application's VNRecognizeTextRequest's alloc()'s init()
-- Set the recognition language (uncomment to use)
-- (theRequest's setRecognitionLanguages:{"ar"}) -- e.g. "ar" for Arabic
-- Perform the request and get the results
requestHandler's performRequests:(current application's NSArray's arrayWithObject:(theRequest)) |error|:(missing value)
set theResults to theRequest's results()
-- Obtain and store the recognized text
set theText to ""
repeat with observation in theResults
set recognizedText to ((first item in (observation's topCandidates:1))'s |string|() as text)
set theText to theText & recognizedText & linefeed
end repeat
-- Create the output path with the same filename but .txt extension
set imageDirectory to (do shell script "dirname " & quoted form of imagePath)
set imageFileNameWithoutExtension to (do shell script "basename " & quoted form of imagePath & " | cut -d. -f1")
set outputPath to imageDirectory & "/" & imageFileNameWithoutExtension & ".txt"
-- Save the recognized text to a file in the same folder as the image
set fileRef to open for access (outputPath as POSIX file) with write permission
try
-- Just write without setting encoding (uncomment next line and comment out UTF8 block beneath)
-- write theText to fileRef
-- Set UTF8 encoding
set theText to (current application's NSString's stringWithString:theText)
set theData to (theText's dataUsingEncoding:(current application's NSUTF8StringEncoding))
(theData's writeToFile:outputPath atomically:true)
on error errMsg
error "Failed to write to file: " & outputPath & return & errMsg
end try
close access fileRef
end repeat
-- Optionally, add a delay between batches to prevent overwhelming the system
delay 1 -- Wait for 1 second (adjust as necessary)
end repeat
-- Return a completion message
return "Text recognition completed for all files."
end run
-- Command line version
-- usage:
-- osascript extract_text_from_image_live_text_ocr.applescript ~/Desktop/test/*.gif
use framework "Vision"
use framework "Foundation"
use scripting additions -- For file operations
on run argv
repeat with imagePath in argv
-- Convert file path to POSIX path
set imagePath to POSIX path of imagePath
-- Ensure the file exists before attempting to process
if not (do shell script "test -f " & quoted form of imagePath & "; echo $?") = "0" then
log "Error: File does not exist at path: " & imagePath
error "File does not exist at path: " & imagePath
end if
-- Convert to NSURL
set fileURL to (current application's NSURL's fileURLWithPath:imagePath)
-- Get image content
set theImage to (current application's NSImage's alloc()'s initWithContentsOfURL:fileURL)
if theImage is missing value then
log "Error: Image could not be loaded at path: " & imagePath
error "Image could not be loaded at path: " & imagePath
end if
-- Set up request handler using image's raw data
set imageData to theImage's TIFFRepresentation()
if imageData is missing value then
log "Error: Failed to extract TIFF representation for image: " & imagePath
error "Failed to extract TIFF representation."
end if
set requestHandler to (current application's VNImageRequestHandler's alloc()'s initWithData:imageData options:(current application's NSDictionary's alloc()'s init()))
-- Initialize text request
set theRequest to current application's VNRecognizeTextRequest's alloc()'s init()
-- Perform the request and get the results
(requestHandler's performRequests:(current application's NSArray's arrayWithObject:(theRequest)) |error|:(missing value))
set theResults to theRequest's results()
-- Obtain and return the string values of the results
set theText to ""
repeat with observation in theResults
set recognizedText to ((first item in (observation's topCandidates:1))'s |string|() as text)
set theText to theText & recognizedText & linefeed
end repeat
-- Get the directory and filename of the image
set imageDirectory to (do shell script "dirname " & quoted form of imagePath)
set imageFileNameWithoutExtension to (do shell script "basename " & quoted form of imagePath & " | cut -d. -f1")
-- Create the output path with the same filename but .txt extension
set outputPath to imageDirectory & "/" & imageFileNameWithoutExtension & ".txt"
-- Save the recognized text to a file in the same folder as the image
set fileRef to open for access (outputPath as POSIX file) with write permission
write theText to fileRef
close access fileRef
-- Log the successful processing
log "Text extracted and saved to: " & outputPath
end repeat
end run
@jvarn
Copy link
Author

jvarn commented Mar 11, 2025

Thanks to Soufien Mestaoui for adding language selection and UTF8 encoding support.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment