Searching for Text in a photo

System Info: late 2012 MacMini, MacOS Catalina (10.15.7)


I'd like to be able to search a group of photos in a folder, for text. (for example, I may want to see all of the photos in this folder that have the text "John Doe" in the photo. (I've done a Google search on this, and I have found where, apparently I can do this via the Apple Photos app, but it appears that to do this, I have to first ingest all of these photos into Apple Photos. I don't want to do this, as I have no reason, aside from this, to even have this folder in Photos. Further, in looking at Photos, it appears that as I add new photos to this folder, I would have to manually add them into Photos, which again, I don't want to do.

So I'm looking for a way where, preferably, just from within Finder/MacOS, I can search for text in a photo, or, at best, to be able to open Photos, and specify this particular folder, and search for my text. Basically, I just need a "quick and dirty" way of saying, "Show me all images in this folder that contain the text "Macbook Pro". This would be my MAIN need for this, secondarily would be to be able to search "this mac" for all photos containing [a particular text string]. Neither of these instances would work (or at least be easy to do) in Photos.


Your help is appreciated.

Earlier Mac models

Posted on Feb 27, 2024 8:11 AM

Reply
Question marked as Best reply

Posted on Feb 27, 2024 7:30 PM

The following AppleScript will prompt you for the folder containing your screen captures. The image format is not important. It will also prompt you for the word or string of words that you want to match in the OCR'd image text. If there is a match, then the filename will be appended to a text file on the Desktop (matchfile.txt).


Copy and paste the following AppleScript code into Apple's Script Editor, click the hammer icon to compile the script, and then click Run. The code required to output to a scrollable window is double the code shown here and I have opted to write the matching files to a text file instead.


use framework "Foundation"
use framework "Vision"
use AppleScript version "2.4" -- macOS Yosemite 10.10 or later
use scripting additions

property ca : current application
-- this will process all images. If just png then "public.png" or jpg then "public.jpeg"
property screen_shot_uttype : "public.image"
property outFile : POSIX path of ((path to desktop as text) & "matchfiles.txt") as text

set theDir to POSIX path of (choose folder default location (path to desktop)) as text
set the imgStr to (text returned of (display dialog "Enter image text search string: " default answer "")) as text
set matchedFile to ca's NSMutableString's new()

-- a list of all images in the selected folder of type screen_shot_uttype
set imgList to paragraphs of (do shell script "mdfind -onlyin " & theDir & " 'kMDItemContentTypeTree == \"" & screen_shot_uttype & "\"'")
set imgArray to ca's NSArray's arrayWithArray:imgList

-- heading
matchedFile's setString:("Files found that have string: " & imgStr & " in them.")
matchedFile's appendString:(return & return)

repeat with anImage in imgArray
	
	set tildeFileName to ((ca's NSString's stringWithString:(anImage as text))'s stringByAbbreviatingWithTildeInPath()) as text
	set ocrText to my getImageText(anImage)
	-- deal with multi-line text returned as list items and turn it into a return punctuated string
	if class of ocrText is list then
		set ocrText to ((ca's NSArray's arrayWithArray:ocrText)'s componentsJoinedByString:return) as text
	end if
	
	-- do we have a match in the OCR'd image text
	if ((offset of imgStr in ocrText) is greater than 0) = true then
		(matchedFile's appendString:tildeFileName)
		(matchedFile's appendString:return)
	end if
	
end repeat
-- output file
matchedFile's writeToFile:outFile atomically:true encoding:(ca's NSUTF8StringEncoding) |error|:(reference)
return

on getImageText(imagePath)
	-- Get image content
	set theImage to ca's NSImage's alloc()'s initWithContentsOfFile:imagePath
	
	-- Set up request handler using image's raw data
	set requestHandler to ca's VNImageRequestHandler's alloc()'s initWithData:(theImage's TIFFRepresentation()) options:(current application's NSDictionary's alloc()'s init())
	
	-- Initialize text request
	set theRequest to ca's VNRecognizeTextRequest's alloc()'s init()
	
	-- Perform the request and get the results
	requestHandler's performRequests:(ca'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
		copy ((first item in (observation's topCandidates:1))'s |string|() as text) to end of theText
	end repeat
	return theText
end getImageText


Let's say I have a screen capture of the following:



In the script's prompt, I enter the following:



and in the Desktop matchfiles.txt there is an entry:




11 replies
Question marked as Best reply

Feb 27, 2024 7:30 PM in response to NHBulldog

The following AppleScript will prompt you for the folder containing your screen captures. The image format is not important. It will also prompt you for the word or string of words that you want to match in the OCR'd image text. If there is a match, then the filename will be appended to a text file on the Desktop (matchfile.txt).


Copy and paste the following AppleScript code into Apple's Script Editor, click the hammer icon to compile the script, and then click Run. The code required to output to a scrollable window is double the code shown here and I have opted to write the matching files to a text file instead.


use framework "Foundation"
use framework "Vision"
use AppleScript version "2.4" -- macOS Yosemite 10.10 or later
use scripting additions

property ca : current application
-- this will process all images. If just png then "public.png" or jpg then "public.jpeg"
property screen_shot_uttype : "public.image"
property outFile : POSIX path of ((path to desktop as text) & "matchfiles.txt") as text

set theDir to POSIX path of (choose folder default location (path to desktop)) as text
set the imgStr to (text returned of (display dialog "Enter image text search string: " default answer "")) as text
set matchedFile to ca's NSMutableString's new()

-- a list of all images in the selected folder of type screen_shot_uttype
set imgList to paragraphs of (do shell script "mdfind -onlyin " & theDir & " 'kMDItemContentTypeTree == \"" & screen_shot_uttype & "\"'")
set imgArray to ca's NSArray's arrayWithArray:imgList

-- heading
matchedFile's setString:("Files found that have string: " & imgStr & " in them.")
matchedFile's appendString:(return & return)

repeat with anImage in imgArray
	
	set tildeFileName to ((ca's NSString's stringWithString:(anImage as text))'s stringByAbbreviatingWithTildeInPath()) as text
	set ocrText to my getImageText(anImage)
	-- deal with multi-line text returned as list items and turn it into a return punctuated string
	if class of ocrText is list then
		set ocrText to ((ca's NSArray's arrayWithArray:ocrText)'s componentsJoinedByString:return) as text
	end if
	
	-- do we have a match in the OCR'd image text
	if ((offset of imgStr in ocrText) is greater than 0) = true then
		(matchedFile's appendString:tildeFileName)
		(matchedFile's appendString:return)
	end if
	
end repeat
-- output file
matchedFile's writeToFile:outFile atomically:true encoding:(ca's NSUTF8StringEncoding) |error|:(reference)
return

on getImageText(imagePath)
	-- Get image content
	set theImage to ca's NSImage's alloc()'s initWithContentsOfFile:imagePath
	
	-- Set up request handler using image's raw data
	set requestHandler to ca's VNImageRequestHandler's alloc()'s initWithData:(theImage's TIFFRepresentation()) options:(current application's NSDictionary's alloc()'s init())
	
	-- Initialize text request
	set theRequest to ca's VNRecognizeTextRequest's alloc()'s init()
	
	-- Perform the request and get the results
	requestHandler's performRequests:(ca'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
		copy ((first item in (observation's topCandidates:1))'s |string|() as text) to end of theText
	end repeat
	return theText
end getImageText


Let's say I have a screen capture of the following:



In the script's prompt, I enter the following:



and in the Desktop matchfiles.txt there is an entry:




Feb 27, 2024 8:58 AM in response to NHBulldog

As dialabrain already indicated, that is not possible via the Finder or any similar file finder/viewer.


While certain apps (e.g. Photos) do have some limited capability to find text in an image, the emphasis is on limited. Even Adobe recommends that images (jpeg, png, tiff, etc.) be converted to PDF in order to identify/extract text. (See How to extract text from an image.) Even then, you cannot just "search for all files containing a particular text string."

Mar 27, 2024 11:13 AM in response to sakurabit

I copied the entire code I posted above (Feb 27, 2024) and pasted it into Script Editor, clicked compile, and ran it against a folder on my Desktop that contained a screen capture image that had macOS Sonoma 14.1.2 in it. The matchfiles.txt file written to my Desktop contained the path to that screen capture image.


No errors were encountered at all but VNRecognizeTextRequest class requires macOS Catalina (10.15+) or later.


Tested: macOS Sonoma 14.4.1.

Feb 27, 2024 9:09 AM in response to MartinR

Thank you both. I don't really need to "extract" text, just "search by" it. My primary use case would be, I am an Admin on a particular Social Media group. If someone posts something that violates posted group rules, I will take a screenshot (CMD-SHIFT-5) of the offending post. These screenshots are saved in a particular folder. Over time, there have gotten to be quite a few of these, so manually looking at each one becomes more and more cumbersome. So I'd like the ability to (whether via an app, or whatever) say, "Show me all images in the screenshots folder that contain [a particular name]." As you can see, as additional images are added to this folder regularly, having to go in and manually add "new" ones to the app would be a pain, trying to make sure I'm not duplicating something, but likewise not omitting anything. Likewise, having to go through and convert everything to a PDF would be a pain. I looked, I don't see where I can save my screenshots as a PDF, so unless there is another app I should look at, I guess this is a "you can't do that." situation.


Thank you.

Feb 27, 2024 4:08 PM in response to NHBulldog

NHBulldog wrote:
I looked, I don't see where I can save my screenshots as a PDF, so unless there is another app I should look at, I guess this is a "you can't do that." situation.

You can convert images to PDF a number of ways. Preview ... Automator ... Adobe Acrobat ... Acrobat Online Services ... MS Word ... OCR apps ...


Also, you can select files in the Finder, then Control-click the selected files, then choose Quick Actions > Create PDF

Searching for Text in a photo

Welcome to Apple Support Community
A forum where Apple customers help each other with their products. Get started with your Apple ID.