Appearance
Image to Text
Prov1.0.3Extract text from an image, right in your browser
Image to Text is a Pro app
It needs a free KimtOS account and a Pro subscription. Everything still runs on your device — Pro unlocks the app, it does not send your data anywhere. Install it without Pro and the app opens to an upgrade wall. See what Pro includes
Overview
Image to Text pulls the words out of an image. Upload, drop, or paste a screenshot, photo, or scan and it runs optical character recognition (OCR) to give you back selectable, copyable text. It is part of the kimtos new-tab app suite.
Everything is fully on-device. There is no backend, no account, and no upload: the OCR engine runs inside your browser, and the image never leaves the machine.
Highlights
- Flexible input — choose a file, drag-and-drop an image onto the dropzone, or paste one straight from the clipboard (
⌘/Ctrl+V). Supports PNG, JPG, WEBP, GIF, and more. - Live preview — the picked image shows in a framed preview before and after extraction, with a one-click view full size lightbox.
- In-browser OCR — text is recognized by Tesseract.js (WebAssembly), with a progress bar that tracks the loading and recognizing steps.
- Readable result — the extracted text appears first, with a word count, and the source image sits just below it.
- Copy & download — copy the text to the clipboard or save it as a
snaptext.txtfile. - History sidebar — every extraction is saved locally as a scan. Revisit a past run, re-copy its text, or batch-delete several at once with one-tap undo.
- Language choice — defaults to English; set another Tesseract language code (for example
ara,fra,deu) in settings. - Layout choice — the page is analysed automatically, so headings, columns and sidebars are all picked up; settings let you force a different reading if a particular image needs it.
Privacy model
Image to Text never sends your image anywhere:
- OCR runs in the browser via a self-hosted Tesseract.js WebAssembly worker. The picture is read on the device and is not uploaded.
- English language data is bundled with the extension, so English OCR works fully offline with no download.
- History (the extracted text plus the original image) is stored only in your browser, and is included in the suite's local backup. Uninstalling the app can erase it.
The model compiles once and is then cached, so later runs are fast and continue to work offline.
Getting Started
Open Image to Text from the dock. The left sidebar holds your past scans; the main pane starts on a fresh input screen, ready for an image.
Provide an image
There are three ways to load a picture:
- Upload — click the dropzone (Drop or paste an image, or click to browse) to pick a file. PNG, JPG, WEBP, GIF, and similar formats are accepted.
- Drag-and-drop — drag an image file from your desktop onto the dropzone.
- Paste — copy an image anywhere, then press
⌘/Ctrl+Vwhile the app is open.
Once loaded, the dropzone is replaced by a preview showing the image, its filename, and size. Hover the preview and click the zoom button to open it full size in a lightbox (click outside or press Esc to close). Click Remove to clear it and start again.
Extract the text
Click Extract text. A progress bar shows the engine's steps — loading the core/language data, then Recognizing text — under the heading Reading the image…. The first run compiles the OCR engine; afterwards it is cached and much faster.
View the result
When recognition finishes, the result pane shows:
- The extracted text first, in a labelled, read-only box with a word count.
- The original image preview just below it (again with the full-size zoom lightbox).
If no text is found, the box reads (no text found).
Copy and download
From the result actions you can:
- Copy — copy the extracted text to the clipboard.
- Download .txt — save the text as
snaptext.txt. - Start over — return to the input screen for another image.
History
Each successful extraction is saved to the history sidebar as a scan (the text plus the source image), newest first.
- Open a scan to view its text and image again.
- Right-click a scan for quick actions — Open, Copy text, Download .txt.
- Delete several — click Select, tick the scans (or drag across them), then Delete (N). A toast lets you undo for a few seconds.
Language settings
Image to Text recognizes English by default. To read another script, open the app's settings and change the Language field to a Tesseract language code — for example ara (Arabic), fra (French), or deu (German). English data ships with the app; other languages are downloaded on first use and then cached.
Layout settings
Before reading an image, the OCR engine has to decide how the page is laid out. Image to Text analyses it automatically, which is what you want for almost every image: titles, columns, sidebars and body text are all found, and they are returned in reading order.
The settings Layout field lets you override that when a particular image reads better another way:
| Layout | Use it for |
|---|---|
| Automatic | The default. Anything with a mix of headings, columns, or page furniture. |
| Single column | One column of text at varying sizes, with nothing beside it. |
| Single block | A crop containing exactly one uniform block of text and nothing else. |
| Scattered text | Signs, labels, diagrams — text dotted around with no page structure. |
Architecture
Image to Text is intentionally thin. It is built on the suite's shared media → text factory, so the descriptor declares the copy and settings while the heavy lifting is a single on-device OCR engine. The code lives in extension/src/apps/snaptext/ and extension/src/lib/engines/.
Modules
| File | Role |
|---|---|
apps/snaptext/index.ts | The app descriptor — id, name, accent, settings (language, layout), and the run hook. Wires the image input to the OCR engine via createMediaTextApp. |
lib/createMediaTextApp.ts | The shared "media in → text out" factory — history sidebar, progress bar, result view, copy/download, and on-device data handling. |
components/imageInput.ts | The input control — upload, drag-and-drop, and clipboard paste, with a framed preview and validation. |
components/imagePanel.ts | The image preview frame with a view full size button. |
components/lightbox.ts | The full-screen image viewer (a native modal <dialog>). |
components/resultView.ts | The text result card — word count plus Copy, Download .txt, and Start over. |
lib/engines/ocr.ts | The OCR engine — runs Tesseract.js (WebAssembly) in a self-hosted worker, sets the page-segmentation mode, and returns the recognized text. |
Data flow
The image is captured as a blob in the browser, handed to recognizeText, and read entirely on-device. Nothing is uploaded.
The OCR engine
engines/ocr.ts lazy-imports Tesseract.js and creates a worker for the chosen language, then calls worker.recognize(file) and returns the trimmed text.
A few details keep it private and offline-friendly:
- Self-hosted worker + core. The worker script (
/ocr/worker.min.js) and the WASM core (/ocr/tesseract-core-simd-lstm.wasm.js) are copied into the extension and loaded from root-relative paths. Manifest V3 forbids loading a worker from a CDN, and its CSP bansblob:workers, soworkerBlobURLis set tofalseand the worker file is loaded directly. - Bundled English data. For
eng, the language data (/ocr/eng.traineddata.gz) is bundled and pointed at vialangPath, so English OCR runs with no download. Other languages are served from the suite's own CDN on first use and are then cached — never from a third-party host. - Progress reporting. A logger normalizes Tesseract's status into a
{ phase, label, ratio }shape —downloadwhile loading the core/language,recognizewhile reading the image — which drives the progress bar.
A companion prefetchOcr helper warms the engine (compiles the WASM and loads the bundled English data) ahead of time, so the first real recognition is instant.
Small text on a large page
Tesseract sizes a page from its dominant text and quietly discards anything far below that size as noise — a 24px footer under a 96px headline is dropped entirely, while the same footer alone on the same canvas reads perfectly. The engine closes that gap with a recovery pass (engines/ocrSmallText.ts): after the main read it scans the image once for horizontal bands of ink, picks out the bands that are much thinner than the page's dominant text and that the main read did not return, then crops just those slivers, enlarges them, and reads them on their own. Recovered lines are spliced back into the text at the place they appear on the page. An image whose text is all one size skips the rescan entirely, so the common screenshot pays only a single cheap scan.
Why on-device
Because the worker, core, and English data are all served from the extension and run as WebAssembly in the browser, Image to Text needs no server and no network for English. The model downloads (when needed) once and is cached; after that it runs offline, and your image stays on the device.
Changelog
1.0.3 — 2026-07-23
- Small text on a busy page — a slide footer under a big headline, a caption, fine print — is no longer silently dropped: the parts the first read misses are found, enlarged and read on their own, then placed back where they appear on the page
1.0.2 — 2026-07-22
- Extraction no longer drops headings, hero titles or sidebar text: the page layout is now analysed automatically instead of being assumed to be one uniform block
- New **Layout** setting — Automatic (default), Single column, Single block, or Scattered text
1.0.1 — 2026-07-22
- The image preview now grows with a maximized or full-screen window, and a tall image no longer covers the extracted text