• Stars
    star
    175
  • Rank 218,059 (Top 5 %)
  • Language
    Python
  • License
    MIT License
  • Created over 2 years ago
  • Updated 6 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Simple MacOS StatusBar / Menu Bar app to automatically detect text in screenshots

Textinator

All Contributors

Simple macOS StatusBar / menu bar app to perform automatic text detection on screenshots.

Overview

Install the app per instructions below. Then, take a screenshot of a region of the screen using ⌘ + ⇧ + 4 (Cmd + Shift + 4). The app will automatically detect any text in the screenshot and copy it to your clipboard.

Watch the screencast

Installation

Download and open the latest installer DMG from the release page then drag the Textinator icon to Applications and follow instructions below to grant Desktop access and optionally grant Full Disk Access.

To launch Textinator the first time you'll need to right-click on the app icon and select "Open" otherwise you may get a warning about unknown developer as the app is not signed with an Apple Developer ID.

Installer DMG

Alternatively, to build from source:

  • clone the repo
  • cd into the repo directory
  • create a virtual environment and activate it
  • python3 -m pip install -r requirements.txt
  • python3 setup.py py2app
  • Copy dist/textinator.app to /Applications
  • Follow instructions below to grant Desktop and optionally Full Disk Access

Grant Desktop access:

Textinator works by monitoring the file system for new screenshots. The macOS security model prevents apps from accessing files and folders without the user's explicit permission. The first time you launch Textinator, you will be prompted to grant it access to your Desktop.

Desktop access

The default location for new screenshots on your Mac is the Desktop folder so Desktop access should be sufficient in most cases. If you want Textinator to detect screenshots in other locations or if you have changed the default location for new screenshots, you will need to grant Full Disk Access.

Grant Full Disk Access:

  • Open System Preferences > Security & Privacy > Full Disk Access
  • Click the padlock if locked to unlock it and add Textinator to the list of allowed apps

System Preferences > Security & Privacy

Upgrading

To upgrade to the latest version, download the latest installer DMG from releases and drag the Textinator icon to Applications. If you have previously granted Textinator Full Disk Access, you will need to remove Textinator from Full Disk Access and re-add it per the instructions above. (This is a limitation of the macOS security model and not something Textinator can control.)

Usage

  • Launch Textinator from the Applications folder
  • Grant Desktop access if prompted
  • Click the menu bar icon to see preferences

Menu Bar Icon

  • Press ⌘ + ⇧ + 4 (Cmd + Shift + 4) to take a screenshot then paste the detected text wherever you'd like it to be.

  • Textinator can also monitor the clipboard for changes which means you can also copy an image from any app or press Control + ⌘ + ⇧ + 4 (Ctrl + Cmd + Shift + 4) to take a screenshot and copy it to the clipboard without creating a screenshot file. Textinator will then detect any text in the image and copy it to the clipboard, overwriting the copied image. This feature can be disabled by unchecking the "Detect text in images on clipboard" checkbox in the menu.

  • You can also use Textinator from the Services menu in Finder (and other apps). To use this feature, right click on an image file in Finder and select Services > Detect text with Textinator from the context menu. Alternatively, you can select Finder > Services > Detect text with Textinator from the menu bar.

Settings

  • Text detection threshold confidence: The confidence threshold for text detection. The higher the value, the more accurate the text detection will be but a higher setting may result in some text not being detected (because the detected text was below the specified threshold). The default value is 'Low' which is equivalent to a VNRecognizeTextRequest confidence threshold of 0.3 (Medium = 0.5, High = 0.8).
  • Text recognition language: Select language for text recognition (languages listed by ISO code and are limited to those which your version of macOS supports).
  • Always detect English: If checked, always attempts to detect English text in addition to the primary language selected by Text recognition language setting.
  • Detect text in images on clipboard: If checked, Textinator will monitor the clipboard for changes and detect any text in any images copied to the clipboard. This feature can be disabled by unchecking the "Detect text in images on clipboard" checkbox in the menu.
  • Pause text detection: If checked, Textinator will not detect text in screenshots or images copied to the clipboard. If paused, the menu bar icon will change and the menu will show Resume text detection instead of Pause text detection.
  • Detect QR Codes: In addition to detecting text, also detect QR codes and copy the decoded payload text to the clipboard.
  • Notification: Whether or not to show a notification when text is detected.
  • Keep linebreaks: Whether or not to keep linebreaks in the detected text; if not set, linebreaks will be stripped.
  • Append to clipboard: Append to the clipboard instead of overwriting it.
  • Clear clipboard: Clear the clipboard.
  • Confirm clipboard changes: Show a confirmation dialog with detected text before copying to the clipboard.
  • Start Textinator on login: Add Textinator to the Login Items list so it will launch automatically when you login. This will cause Textinator to prompt for permission to send AppleScript events to the System Events app (see screnshot below).
  • About Textinator: Show the about dialog.
  • Quit Textinator: Quit Textinator.

When you first select Start Textinator on login, you will be prompted to allow Textinator to send AppleScript events to the System Events app. This is required to add Textinator to the Login Items list. The screenshot below shows the prompt you will see.

System Events permission

Inspiration

I heard mikeckennedy mention Text Sniper on Python Bytes podcast #284 and thought "That's neat! I bet I could make a clone in Python!" and here it is. You should listen to Python Bytes if you don't already and you should go buy Text Sniper!

This project took a few hours and the whole thing is a few hundred lines of Python. It was fun to show that you can build a really useful macOS native app in just a little bit of Python.

Textinator was featured on Talk Python to Me! Thanks Michael Kennedy for hosting me!

How Textinator Works

Textinator is built with rumps (Ridiculously Uncomplicated macOS Python Statusbar apps) which is a python package for creating simple macOS Statusbar apps.

At startup, Textinator starts a persistent NSMetadataQuery Spotlight query (using the pyobjc Python-to-Objective-C bridge) to detect when a new screenshot is created.

When the user creates screenshot, the NSMetadataQuery query is fired and Textinator performs text detection using a Vision VNRecognizeTextRequest call.

Textinator can also monitor the clipboard and detect text in images copied to the clipboard.

Notes

  • If building with pyenv installed python, you'll need to build the python with framework support:
    • env PYTHON_CONFIGURE_OPTS="--enable-framework" pyenv install -v 3.9.11
  • Requires a minimum of macOS Catalina (10.15). Tested on macOS Catalina (10.15.7) and Big Sur (11.6.4); should work on Catalina or newer.

License

MIT License

See Also

Text Sniper which inspired this project.

Contributors ✨

Thanks goes to these wonderful people (emoji key):

Bernhard Wagner
Bernhard Wagner

🤔 💻

This project follows the all-contributors specification. Contributions of any kind welcome!

Developer Notes

If you want to build Textinator yourself, here are some notes:

Install requirements and development requirements via pip:

python3 -m pip install -r requirements.txt python3 -m pip install -r dev_requirements.txt

Building the DMG for distribution requires create-dmg which can be installed with homebrew:

brew install create-dmg

To build Textinator, run the build.sh script:

./build.sh

This script cleans out old build files, builds the app with py2app, signs the app, and builds the DMG.

Textinator stores it's preferences in ~/Library/Application\ Support/Textinator/Textinator.plist. This is non-standard (by convention, apps store their preferences in ~/Library/Preferences/), but RUMPS doesn't provide a method to access the Preferences folder and it does provide a method to access the Application Support folder (rumps.App.open()), so I went with that.

The preferences can be read from the command line with:

defaults read ~/Library/Application\ Support/Textinator/Textinator.plist

For development and debugging it may be helpful to enable the debug log by setting debug=1 in Textinator.plist. You can do this from the command line with:

defaults write ~/Library/Application\ Support/Textinator/Textinator.plist debug -bool true

Similarly, you can disable the debug log with:

defaults write ~/Library/Application\ Support/Textinator/Textinator.plist debug -bool false

When debug is enabled, Textinator will log to ~/Library/Application\ Support/Textinator/Textinator.log. I find this more convenient than using the macOS Console app. Textinator will always log to the Console log as well so you can use Console if you prefer and filter on Textinator.

Most features of the app can be tested by simply running the textinator.py script: python3 src/textinator.py. The Services menu feature requires the app be built and installed because it needs runtime access to information in the app bundle's Info.plist which is built by py2app.

The version number is incremented by bump2version which is installed via python3 -m pip install -r dev_requirements.txt. To increment the version number, run bumpversion patch or bumpversion minor or bumpversion major as appropriate. See bumpversion --help for more information.

I've tried to document the code well so that you can use Textinator as a template for your own apps. Some of the features (such as creating a Services menu item) are not well documented (especially with respect to doing these things in python) and took me a lot of trial and error to figure out. I hope that this project will help others who want to build macOS native apps in python.

Testing

Textinator uses pytest to run unit tests. To run the tests, run pytest from the project root directory. Before running the tests, you'll need to install the development requirements via python3 -m pip install -r dev_requirements.txt. You will also need to enable your Terminal app to control your computer in System Preferences > Security & Privacy > Privacy > Accessibility. This is because the testing uses System Events scripting via applescript to simulate user actions such as clicking menu items.

The test suite requires the built app to be installed in /Applications/Textinator.app. Before running tests, uses ./build.sh to build the app then copy dist/Textinator.app to /Applications/Textinator.app.

The tests will modify the Textinator preferences but will backup your original preferences and restore them when testing is completed. The tests will also modify the clipboard and will create temporary files on the Desktop which will be cleaned up when testing is completed.

The test suite is slow due to required sleeps to allow the app to respond, Spotlight to index new files, etc. (Takes approximately 5 minutes to run on my MacBook Pro). Because the test suite interacts with the user interface, it is best not to touch the keyboard or mouse while the tests are running.

The Services menu item is not tested by the test suite so this feature should be tested manually.

More Repositories

1

osxphotos

Python app to work with pictures and associated metadata from Apple Photos on macOS. Also includes a package to provide programmatic access to the Photos library, pictures, and metadata.
Python
2,003
star
2

macnotesapp

Work with Apple MacOS Notes.app from the command line. Also includes python interface for scripting Notes.app from your own python code.
Python
129
star
3

osxmetadata

Python package to read and write various MacOS extended attribute metadata such as tags/keywords and Finder comments from files. Includes CLI tool for reading/writing metadata.
Python
117
star
4

PhotoScript

Automate Apple / MacOS Photos app with python. Wraps applescript calls in python to allow automation of Photos from python code.
Python
47
star
5

photosmeta

Extract known metadata from Apple's MacOS Photos library and export this metadata to EXIF/IPTC/XMP fields in the photo file For example: Photos knows about Faces (personInImage) but does not preserve this data when exporting the original photo.
Python
41
star
6

applecrate

Package your command line tools into a native macOS installer.
Python
34
star
7

makelive

Create Live Photos from a photo+video pair compatible with Apple Photos
Python
27
star
8

exif2findertags

Read EXIF metadata from image and video files and convert it to macOS Finder tags and/or Finder comments.
Python
21
star
9

autofile

Mac command line app to automatically move or copy files based on metadata associated with the files. For example, file your photos based on EXIF metadata or use MP3 tags to file your music files.
Python
21
star
10

locationator

A simple macOS menubar app that provides access to the macOS Location Services reverse geocoding API via a local web server as well as a command line tool.
Python
20
star
11

guitk

Python GUI Toolkit for Tk (guitk): simplify the layout and construction of tkinter graphical user interfaces in python using a declarative syntax.
Python
17
star
12

RepairPhotosBookmarks

Repair broken bookmarks to referenced files in Apple Photos to fix "Missing file" errors when moving a Photos library to a different disk or machine.
Python
14
star
13

apple-news-to-sqlite

Export Apple News saved articles to SQLite
Python
13
star
14

photos_time_warp

Batch adjust the date, time, or timezone of photos in Apple Photos from the Mac command line.
Python
11
star
15

appkitgui

Example python project demonstrating how to create a native macOS GUI with AppKit and PyObjC
Python
11
star
16

sqlitekvstore

Simple persistent key-value store for python backed by a sqlite database
Python
10
star
17

rich_theme_manager

Implements a basic "theme manager" class for managing rich Themes in your rich python CLI application.
Python
10
star
18

add_photo_locations_from_gpx

Add missing location data to photos in Apple's Photos app using data from a GPX file
Python
9
star
19

dirsnapshot

Diff for directories; create snapshots of directories and compare/diff these to the directory or another snapshot
Python
8
star
20

photokit

Python package for accessing the macOS Photos.app library via Apple's native PhotoKit framework
Python
8
star
21

ChargeMon

Simple macOS StatusBar app to remind you to unplug your laptop when sufficiently charged
Python
8
star
22

add_photo_locations_from_google_history

Python script to add missing location data to photos in your Apple Photos library based on your Google location history. This script can be run stand-alone to add location data to the photos in your library or as a post-processing function for osxphotos to add location data to photos upon export.
Python
7
star
23

mdinfo

Output metadata information for files in various formats using a template system
Python
7
star
24

macos_mditem_metadata

Access macOS Spotlight metadata on files from Python. Also includes JSON data for all common metadata keys.
Python
6
star
25

rich_theme_printer

Use rich python package to print color palette from a Visual Studio Code (VSCode) color theme JSON file
Python
6
star
26

exif2spotlight

Read exif metadata from images with exiftool and write to MacOS Spotlight searchable extended attributes
Python
6
star
27

PyImageSnap

Python implementation of Robert Harder's imagesnap utility for Mac. Command line tool to take photos using Mac’s built in camera or an attached USB camera.
Python
5
star
28

yep2tag

Export metadata from Ironic Software's Yep application to OS X native tags and Finder comments
Python
5
star
29

sqlgrep

grep for sqlite databases
Python
5
star
30

clirunner

A python test helper for invoking and testing command line interfaces (CLIs) based on Click's CliRunner
Python
5
star
31

datetime-utils

A handful of small utility functions I find useful for dealing with python datetime objects and timezones
Python
5
star
32

strpdatetime

Parse strings into Python datetime objects; extends Python's datetime.strptime() with additional features.
Python
4
star
33

put_in_pocket

Command line tool to add URLs from the command line or from a file to your Pocket reading list. Designed to add URLs from an email.
Python
4
star
34

mdinfo-exiftool

Exiftool plugin for mdinfo
Python
4
star
35

mdinfo_macos

MacOS plugin for mdinfo providing access to macOS and Spotlight metadata
Python
4
star
36

pystrgrep

grep/search for pattern contained in python string constants inside a python file
Python
3
star
37

Accumulate

iOS accumulation timer app written in python with Pythonista
Python
3
star
38

questionary-superprompt

An extension to the python questionary package that provides additional features for the prompt method
Python
3
star
39

pasteboard

macOS pasteboard/clipboard implementation using native NSPasteboard API
Python
3
star
40

adventure-bot

Twitter bot that plays the classic Colossal Cave Adventure game
Python
3
star
41

merge_photos_libraries

Merge Apple Photos libraries
Python
3
star
42

qrlogo

Create QR codes for URLs and automatically add the favicon logo to the QR code
Python
2
star
43

s3dict

python dictionary class providing persistent storage by serializing state to a json file on an Amazon S3 bucket
Python
2
star
44

BrickBrain

Project I did with my son to learn machine learning for his science fair project. Identifies various LEGO-type bricks.
Python
2
star
45

pyapp-builder

This is just a test, nothing to see here.
1
star
46

mobile-dnd-js-demo

Using drag and drop on mobile
1
star
47

Statistics-Descriptive-Discrete

Perl module to compute descriptive statistics on discrete datasets (for example, data that has been quantized by an A/D converter)
Perl
1
star
48

CGMetadata

Use native ImageIO / Core Graphics API on macOS from Python to access and change image metadata
Python
1
star
49

crash-catcher

Decorator to catch exceptions in a python function and log them to a file.
Python
1
star