{"id":20287591,"url":"https://github.com/rhettbull/textinator","last_synced_at":"2026-03-01T14:34:28.893Z","repository":{"id":41608014,"uuid":"502206991","full_name":"RhetTbull/textinator","owner":"RhetTbull","description":"Simple MacOS StatusBar / Menu Bar app to automatically detect text in screenshots","archived":false,"fork":false,"pushed_at":"2024-05-04T23:53:38.000Z","size":3601,"stargazers_count":188,"open_issues_count":4,"forks_count":9,"subscribers_count":7,"default_branch":"main","last_synced_at":"2025-05-08T00:09:27.666Z","etag":null,"topics":["macos","menubar","menubar-app","menubarapp","ocr","osx","screenshot","utility"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/RhetTbull.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-06-10T23:39:15.000Z","updated_at":"2025-04-17T11:07:46.000Z","dependencies_parsed_at":"2024-11-06T03:32:27.379Z","dependency_job_id":null,"html_url":"https://github.com/RhetTbull/textinator","commit_stats":null,"previous_names":[],"tags_count":11,"template":false,"template_full_name":null,"purl":"pkg:github/RhetTbull/textinator","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RhetTbull%2Ftextinator","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RhetTbull%2Ftextinator/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RhetTbull%2Ftextinator/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RhetTbull%2Ftextinator/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/RhetTbull","download_url":"https://codeload.github.com/RhetTbull/textinator/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RhetTbull%2Ftextinator/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29970994,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-01T14:11:48.712Z","status":"ssl_error","status_checked_at":"2026-03-01T14:11:48.352Z","response_time":124,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["macos","menubar","menubar-app","menubarapp","ocr","osx","screenshot","utility"],"created_at":"2024-11-14T14:40:48.639Z","updated_at":"2026-03-01T14:34:28.873Z","avatar_url":"https://github.com/RhetTbull.png","language":"Python","readme":"# Textinator\n\u003c!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section --\u003e\n[![All Contributors](https://img.shields.io/badge/all_contributors-1-orange.svg?style=flat)](#contributors)\n\u003c!-- ALL-CONTRIBUTORS-BADGE:END --\u003e\n\nSimple macOS StatusBar / menu bar app to perform automatic text detection on screenshots.\n\n## Overview\n\nInstall the app per [instructions](#installation) 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.\n\n[![Watch the screencast](https://img.youtube.com/vi/K_3MXOeBBdY/maxresdefault.jpg)](https://youtu.be/K_3MXOeBBdY)\n\n## Installation\n\nDownload and open the latest installer DMG from the [release](https://github.com/RhetTbull/textinator/releases) page then drag the Textinator icon to Applications and follow instructions below to grant Desktop access and optionally grant Full Disk Access.\n\nTo 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.\n\n![Installer DMG](images/installer.png)\n\nAlternatively, to build from source:\n\n- clone the repo\n- cd into the repo directory\n- create a virtual environment and activate it\n- python3 -m pip install -r requirements.txt\n- python3 setup.py py2app\n- Copy dist/textinator.app to /Applications\n- Follow instructions below to grant Desktop and optionally Full Disk Access\n\nSee also [Developer Notes](#developer-notes) below.\n\nGrant Desktop access:\n\nTextinator 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.\n\n![Desktop access](images/textinator_desktop_access.png)\n\nThe 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](https://support.apple.com/en-us/HT201361), you will need to grant Full Disk Access.\n\nGrant Full Disk Access:\n\n- Open System Settings...\u003ePrivacy \u0026 Security\u003e Full Disk Access\n- Click the padlock if locked to unlock it and add Textinator to the list of allowed apps\n\n![System Preferences \u003e Security \u0026 Privacy](images/Full_Disk_Access.png)\n\n## Upgrading\n\nTo upgrade to the latest version, download the latest installer DMG from [releases](https://github.com/RhetTbull/textinator/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.)\n\n## Usage\n\n- Launch Textinator from the Applications folder\n- Grant Desktop access if prompted\n- Click the menu bar icon to see preferences\n\n![Menu Bar Icon](images/textinator_settings.png)\n\n- Press ⌘ + ⇧ + 4 (`Cmd + Shift + 4`) to take a screenshot then paste the detected text wherever you'd like it to be.\n\n- 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.\n\n- You can also use Textinator from the [Services menu](https://macreports.com/what-is-the-services-menu-in-macos/) in Finder (and other apps). To use this feature, right click on an image file in Finder and select `Services \u003e Detect Text With Textinator` from the context menu. Alternatively, you can select `Finder \u003e Services \u003e Detect text with Textinator` from the menu bar.\n\n## Settings\n\n- `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](https://developer.apple.com/documentation/vision/vnrecognizetextrequest?language=objc) confidence threshold of `0.3` (Medium = `0.5`, High = `0.8`).\n- `Text recognition language`: Select language for text recognition (languages listed by [ISO code](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes) and are limited to those which your version of macOS supports).\n- `Always detect English`: If checked, always attempts to detect English text in addition to the primary language selected by `Text recognition language` setting.\n- `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.\n- `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`.\n- `Detect QR Codes`: In addition to detecting text, also detect QR codes and copy the decoded payload text to the clipboard.\n- `Notification`: Whether or not to show a notification when text is detected.\n- `Keep linebreaks`: Whether or not to keep linebreaks in the detected text; if not set, linebreaks will be stripped.\n- `Append to clipboard`: Append to the clipboard instead of overwriting it.\n- `Clear clipboard`: Clear the clipboard.\n- `Confirm clipboard changes`: Show a confirmation dialog with detected text before copying to the clipboard.\n- `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).\n- `About Textinator`: Show the about dialog.\n- `Quit Textinator`: Quit Textinator.\n\nWhen 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.\n\n![System Events permission](images/system_events_access.png)\n\n## Inspiration\n\nI heard [mikeckennedy](https://github.com/mikeckennedy) mention [Text Sniper](https://textsniper.app/) on [Python Bytes](https://pythonbytes.fm/) podcast [#284](https://pythonbytes.fm/episodes/show/284/spicy-git-for-engineers) 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!\n\nThis 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.\n\nTextinator was featured on [Talk Python to Me](https://www.youtube.com/watch?v=ndFFgJhrUhQ\u0026t=810s)! Thanks [Michael Kennedy](https://twitter.com/mkennedy) for hosting me!\n\n## How Textinator Works\n\nTextinator is built with [rumps (Ridiculously Uncomplicated macOS Python Statusbar apps)](https://github.com/jaredks/rumps) which is a python package for creating simple macOS Statusbar apps.\n\nAt startup, Textinator starts a persistent [NSMetadataQuery Spotlight query](https://developer.apple.com/documentation/foundation/nsmetadataquery?language=objc) (using the [pyobjc](https://pyobjc.readthedocs.io/en/latest/) Python-to-Objective-C bridge) to detect when a new screenshot is created.\n\nWhen the user creates screenshot, the `NSMetadataQuery` query is fired and Textinator performs text detection using a [Vision](https://developer.apple.com/documentation/vision?language=objc) [VNRecognizeTextRequest](https://developer.apple.com/documentation/vision/vnrecognizetextrequest?language=objc) call.\n\nTextinator can also monitor the clipboard and detect text in images copied to the clipboard.\n\n## Notes\n\n- If building with [pyenv](https://github.com/pyenv/pyenv) installed python, you'll need to build the python with framework support:\n  - `env PYTHON_CONFIGURE_OPTS=\"--enable-framework\" pyenv install -v 3.9.11`\n- Requires a minimum of macOS Catalina (10.15).  Tested on macOS Catalina (10.15.7), Big Sur (11.6.4), Ventura (13.5.1); should work on Catalina or newer.\n\n## License\n\nMIT License\n\n## See Also\n\n[Text Sniper](https://textsniper.app/) which inspired this project.\n\n## Contributors ✨\n\nThanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)):\n\n\u003c!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section --\u003e\n\u003c!-- prettier-ignore-start --\u003e\n\u003c!-- markdownlint-disable --\u003e\n\u003ctable\u003e\n  \u003ctbody\u003e\n    \u003ctr\u003e\n      \u003ctd align=\"center\" valign=\"top\" width=\"14.28%\"\u003e\u003ca href=\"https://github.com/bwagner\"\u003e\u003cimg src=\"https://avatars.githubusercontent.com/u/447049?v=4?s=75\" width=\"75px;\" alt=\"Bernhard Wagner\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eBernhard Wagner\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"#ideas-bwagner\" title=\"Ideas, Planning, \u0026 Feedback\"\u003e🤔\u003c/a\u003e \u003ca href=\"https://github.com/RhetTbull/textinator/commits?author=bwagner\" title=\"Code\"\u003e💻\u003c/a\u003e \u003ca href=\"https://github.com/RhetTbull/textinator/commits?author=bwagner\" title=\"Tests\"\u003e⚠️\u003c/a\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\n\u003c!-- markdownlint-restore --\u003e\n\u003c!-- prettier-ignore-end --\u003e\n\n\u003c!-- ALL-CONTRIBUTORS-LIST:END --\u003e\n\nThis project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome!\n\n## Developer Notes\n\nIf you want to work on Textinator yourself or contribute changes, here are some notes:\n\nClone the repo and cd into the repo directory.\n\n`git clone git@github.com:RhetTbull/textinator.git`\n`cd textinator`\n\nIf you want to contribute back to Textinator, fork the repo and clone your fork instead.\n\nInstall requirements and development requirements via pip:\n\n```console\npython3 -m pip install -r requirements.txt -r dev_requirements.txt\npre-commit install\n```\n\nSee also notes below about [Testing](#testing).\n\nBuilding the DMG for distribution requires [create-dmg](https://github.com/create-dmg/create-dmg) which can be installed with [homebrew](https://brew.sh/):\n\n`brew install create-dmg`\n\nTo build Textinator, run the `build.sh` script:\n\n`./build.sh`\n\nThis script cleans out old build files, builds the app with [py2app](https://py2app.readthedocs.io/en/latest/), signs the app, and builds the DMG.\n\nTextinator 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.\n\nThe preferences can be read from the command line with:\n\n`defaults read ~/Library/Application\\ Support/Textinator/Textinator.plist`\n\nFor 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:\n\n`defaults write ~/Library/Application\\ Support/Textinator/Textinator.plist debug -bool true`\n\nSimilarly, you can disable the debug log with:\n\n`defaults write ~/Library/Application\\ Support/Textinator/Textinator.plist debug -bool false`\n\nWhen `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`.\n\nMost 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`.\n\nThe version number is incremented by [bump2version](https://github.com/c4urself/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.\n\nI'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.\n\n## Testing\n\nTextinator uses [pytest](https://docs.pytest.org/en/7.1.x/) 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 \u003e Security \u0026 Privacy \u003e Privacy \u003e Accessibility`. This is because the testing uses System Events scripting via applescript to simulate user actions such as clicking menu items. Your Terminal will also need to be granted Full Disk Access in `System Preferences \u003e Security \u0026 Privacy \u003e Privacy \u003e Full Disk Access`.\n\nThe 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`.\n\nThe 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.\n\nThe 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 Air). Because the test suite interacts with the user interface, it is best not to touch the keyboard or mouse while the tests are running.\n\nThe Services menu item is not tested by the test suite so this feature should be tested manually.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frhettbull%2Ftextinator","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frhettbull%2Ftextinator","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frhettbull%2Ftextinator/lists"}