# Image OCR Extractor - Image to Text with Word Boxes (`fabrikit/image-ocr-extractor`) Actor

Read the text in images from any URL: JPG, PNG, WebP, GIF, TIFF and BMP screenshots, scans, signs and graphics. Get the full text, every line and word with its position and confidence, and the detected language. 100+ OCR languages.

- **URL**: https://apify.com/fabrikit/image-ocr-extractor.md
- **Developed by:** [Fabrikit](https://apify.com/fabrikit) (community)
- **Categories:** AI, Developer tools, Automation
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.95 / 1,000 image read with ocrs

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Image OCR Extractor - Image to Text with Word Boxes

**Image OCR Extractor** reads the text inside images from any public URL and returns it as clean, structured data. Give it links to JPG, PNG, WebP, GIF, TIFF or BMP files (screenshots, scanned pages, statements, infographics, photos of signs) and each image becomes one dataset record with the full text, every line and word with its pixel position and confidence score, and the language of the text.

OCR runs inside the Actor with the Tesseract engine, the same one used by our [Document to Markdown](https://apify.com/fabrikit/document-to-markdown) Actor. No external OCR API, no API key, no per-call fees from a third party.

### What each record contains

- **`text`**: everything that was read, one line per text line, with an empty line between blocks that are visibly separate (columns, sections).
- **`lines`**: each line with `confidence` (0-100) and its bounding box `x`, `y`, `width`, `height` in pixels of the original image.
- **`words`** (optional): each word with confidence, bounding box and line number, for highlighting, redaction or reading forms by position.
- **Image facts**: `format`, `width`, `height` (upright, after EXIF rotation), `fileSizeBytes`, `frameCount`.
- **Quality signals**: mean `confidence`, `textFound`, `lineCount`, `wordCount`, detected `language` (ISO 639-1), and `notes` with tips when nothing was found.

### Use cases

- Turn screenshots of dashboards, chats, terminals and web pages into searchable text.
- Pull rows out of images of statements, price lists and tables (dates, amounts, reference numbers stay on their line).
- Index image-heavy content (infographics, posters, slides exported as images) for search or for an LLM / RAG pipeline.
- Check product photos, banners and ad creatives for the words they contain, with positions.
- Read street, shop and safety signs in photos for mapping or dataset labelling.

### How to use

1. Paste image links into **Image URLs** (right-click an image in the browser and choose *Copy image address*).
2. Set **OCR language(s)** if the text is not English, for example `spa`, `fra`, `deu` or `eng+spa`.
3. Run the Actor. Download the dataset as JSON, CSV, Excel or HTML, or read it with the API.

#### Input example

```json
{
  "imageUrls": [
    "https://upload.wikimedia.org/wikipedia/commons/5/5e/Panneau_du_Chemin_des_Avias.jpg",
    "https://raw.githubusercontent.com/naptha/tesseract.js/master/tests/assets/images/bill.png"
  ],
  "ocrLanguages": "eng+spa",
  "layout": "auto",
  "minConfidence": 30,
  "includeLines": true,
  "includeWords": true,
  "maskContacts": true,
  "maxItems": 20
}
```

| Option | What it does |
|---|---|
| `ocrLanguages` | Tesseract language codes joined with `+` (up to 5). English and Spanish are built in; other languages are downloaded once per run. |
| `layout` | `auto` for documents, screenshots, tables and sign photos; `sparse` for text scattered around the image (UI screenshots, infographics); `block` for one block of text such as a label or banner; `line` for a single line. |
| `minConfidence` | Lines read with lower confidence are dropped (default 30). Raise it for busy photos. |
| `enhanceImages` | Clean-up before OCR (on by default): grayscale, contrast, inversion of light-on-dark text, enlarging small screenshots, reducing huge photos. |
| `includeLines`, `includeWords` | Turn the position arrays on or off. |
| `maskContacts` | Replaces e-mail addresses and phone numbers with `[email removed]` / `[phone removed]` in text, lines and words (on by default). |
| `maxFileSizeMb` | Skip larger files (default 25 MB, up to 100 MB). |

`imageUrls` also accepts `data:image/png;base64,...` URLs, which is handy when an AI agent or a script already has the image bytes.

#### Output example

Real record for a street sign photo from Wikimedia Commons (1146 x 823 JPEG), shortened only by removing the `processedAt` field:

```json
{
  "imageUrl": "https://upload.wikimedia.org/wikipedia/commons/5/5e/Panneau_du_Chemin_des_Avias.jpg",
  "fileName": "Panneau_du_Chemin_des_Avias.jpg",
  "fileSizeBytes": 182375,
  "format": "jpeg",
  "width": 1146,
  "height": 823,
  "status": "ok",
  "textFound": true,
  "text": "Chemin\ndes Avias",
  "lineCount": 2,
  "wordCount": 3,
  "confidence": 93.6,
  "ocrLanguages": "eng+spa",
  "layout": "auto",
  "lines": [
    { "text": "Chemin", "confidence": 96, "x": 413, "y": 394, "width": 95, "height": 21, "paragraph": 0 },
    { "text": "des Avias", "confidence": 92, "x": 385, "y": 429, "width": 118, "height": 21, "paragraph": 0 }
  ],
  "words": [
    { "text": "Chemin", "confidence": 96, "x": 413, "y": 394, "width": 95, "height": 21, "line": 0 },
    { "text": "des", "confidence": 93, "x": 385, "y": 429, "width": 41, "height": 21, "line": 1 },
    { "text": "Avias", "confidence": 92, "x": 437, "y": 431, "width": 66, "height": 18, "line": 1 }
  ],
  "preprocessing": { "enhanced": true, "scale": 1, "inverted": false, "binarization": "sauvola" },
  "notes": null,
  "ocrSeconds": 0.28
}
```

The bank statement sample in the default input comes back line by line, for example `01Aug2018 Clearing Cheque 4987 36.07 99,914.15 -`.

Links that fail (404, a web page instead of an image, a PDF, a file over the size limit) produce a record with `status: "failed"` and the reason in `error`, and are **not charged**. The `SUMMARY` record in the run's key-value store counts images read, images with text, lines, words and errors.

### Pricing

Pay per event, no subscription:

| Event | When |
|---|---|
| `image-ocr` | each image, once it has been downloaded and read (also when it turns out to contain no text) |

See the Pricing tab for current prices; paid Apify plans get lower rates. Set a maximum cost per run in Apify and the Actor stops cleanly before going over it.

### How it compares

This Actor returns positions and confidence for every line (and optionally every word). Cloud vision APIs can be more accurate on difficult photos and handwriting, but need an account and an API key and bill per request.

Honest limits: Tesseract is built for printed text. Handwriting, very stylised fonts, text curved around objects and tiny text in large photos come out poorly or not at all. Images rotated 90 or 180 degrees without EXIF orientation are not turned upright. Only the first frame of animated GIF/WebP and the first page of multi-page TIFF files is read; for multi-page scans and PDFs use [Document to Markdown](https://apify.com/fabrikit/document-to-markdown). HEIC photos and SVG files are not supported.

### Integrations

- **API and clients**: start runs and fetch results with the Apify API, the JavaScript or Python client, or one synchronous call (`run-sync-get-dataset-items`).
- **Make, Zapier, n8n**: use the Apify modules to send new image links (from a form, a sheet or a storage bucket) and write the text back.
- **AI agents (MCP)**: the Actor can be called as a tool through the Apify MCP server, so an assistant can read an image link, or a base64 `data:` URL, during a conversation.
- **Webhooks**: get notified when a run finishes and push the records to your own endpoint.

### FAQ

**Is it legal?** The Actor only downloads the links you provide, like a browser. Make sure you are allowed to process those images. E-mail addresses and phone numbers are masked by default so personal contact details do not end up in your dataset by accident.

**Do I need a proxy?** No. Images are downloaded directly; if a host refuses (401, 403, 429), the download is retried through Apify datacenter proxy or your own proxy URLs. Residential proxy is not used.

**Which languages?** Any of the 100+ Tesseract languages: `eng` and `spa` are built in, the rest (for example `fra`, `deu`, `por`, `rus`, `ara`, `hin`, `jpn`, `chi_sim`) are downloaded at the start of the run. List only the languages you expect; extra languages slow OCR down and can lower accuracy.

**Why did an image return no text?** Check `notes`. Big isolated words in graphics are retried automatically as one block; for scattered UI text try `layout: "sparse"`, for one line try `"line"`.

**Size limits?** Up to 100 MB per file and about 120 megapixels; very large photos are reduced to 2,600 pixels on the long side before OCR.

**Are my images stored?** No. Each file is deleted right after it is read; only the dataset record stays in your Apify account.

### Changelog

- **0.1** (October 2026): first release. JPG, PNG, WebP, GIF, TIFF, BMP and data: URLs; text, lines and words with boxes and confidence; automatic clean-up and photo-aware binarisation; layout modes; language detection; contact masking; per-image pricing.

### En español

**Image OCR Extractor** lee el texto de imágenes desde cualquier URL pública (JPG, PNG, WebP, GIF, TIFF, BMP): capturas de pantalla, documentos escaneados, estados de cuenta, infografías y fotos de carteles. Por cada imagen devuelve el texto completo, cada línea y cada palabra con su posición en píxeles y su nivel de confianza, y el idioma detectado. Trae inglés y español incluidos y descarga otros idiomas de Tesseract al inicio de la corrida. Oculta por defecto correos y teléfonos. Consulta la pestaña Pricing para ver los precios actuales; los planes de pago de Apify tienen tarifas más bajas. Los enlaces que fallan no se cobran. Para PDF y escaneos de varias páginas usa nuestro [Document to Markdown](https://apify.com/fabrikit/document-to-markdown).

# Actor input Schema

## `imageUrls` (type: `array`):

Direct links to image files, one per line (right-click an image > Copy image address). data:image/...;base64 URLs also work. Duplicates are skipped. Links that return a web page, a PDF or another non-image file are reported as failed and not charged.

## `ocrLanguages` (type: `string`):

Tesseract language codes of the text in the images, joined with +: eng (default), spa, eng+spa, fra, deu, por, ita, nld, rus, ara, hin, jpn, chi_sim, kor... Up to 5. English and Spanish are built in; other languages are downloaded once at the start of the run. Fewer languages = faster and more accurate.

## `layout` (type: `string`):

Auto works for documents, screenshots, tables and photos of signs. Sparse finds scattered text in no particular order (UI screenshots, infographics, diagrams). Single block treats the image as one block of text (a cropped paragraph, a label, a banner). Single line is for images that hold one line of text.

## `minConfidence` (type: `integer`):

Lines that the OCR engine reads with a lower confidence are dropped. They are usually textures, logos or patterns mistaken for letters. Lower it to keep everything, raise it (60-80) for cleaner output from busy photos.

## `enhanceImages` (type: `boolean`):

Grayscale, contrast stretch, light-on-dark text inverted (dark mode, terminals), small screenshots enlarged and huge photos reduced. Turn off only if your images are already prepared for OCR.

## `includeLines` (type: `boolean`):

Add a lines array: the text of each line with its confidence and bounding box (x, y, width, height in pixels of the original image).

## `includeWords` (type: `boolean`):

Add a words array: every word with its confidence, bounding box and line number. Useful to highlight or redact text, or to read forms by position. Makes records larger.

## `maskContacts` (type: `boolean`):

Replace e-mail addresses and phone numbers in the text, lines and words with \[email removed] / \[phone removed]. US toll-free numbers stay. Turn off for your own images when you need them verbatim.

## `maxItems` (type: `integer`):

Maximum number of images to read in this run (the first N links).

## `maxFileSizeMb` (type: `integer`):

Larger files are skipped and reported as failed (not charged).

## `proxyConfiguration` (type: `object`):

Only used to download the images. Each image is downloaded directly first; if the host refuses (401/403/429), the download is retried through Apify datacenter proxy or your own proxy URLs. Residential proxy is not used.

## Actor input object example

```json
{
  "imageUrls": [
    "https://raw.githubusercontent.com/naptha/tesseract.js/master/tests/assets/images/testocr.png",
    "https://raw.githubusercontent.com/naptha/tesseract.js/master/tests/assets/images/bill.png"
  ],
  "ocrLanguages": "eng",
  "layout": "auto",
  "minConfidence": 30,
  "enhanceImages": true,
  "includeLines": true,
  "includeWords": false,
  "maskContacts": true,
  "maxItems": 20,
  "maxFileSizeMb": 25,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `images` (type: `string`):

One item per image link

## `summary` (type: `string`):

Images read and failed, lines and words found, OCR seconds per image, errors

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "imageUrls": [
        "https://raw.githubusercontent.com/naptha/tesseract.js/master/tests/assets/images/testocr.png",
        "https://raw.githubusercontent.com/naptha/tesseract.js/master/tests/assets/images/bill.png"
    ],
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("fabrikit/image-ocr-extractor").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "imageUrls": [
        "https://raw.githubusercontent.com/naptha/tesseract.js/master/tests/assets/images/testocr.png",
        "https://raw.githubusercontent.com/naptha/tesseract.js/master/tests/assets/images/bill.png",
    ],
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("fabrikit/image-ocr-extractor").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "imageUrls": [
    "https://raw.githubusercontent.com/naptha/tesseract.js/master/tests/assets/images/testocr.png",
    "https://raw.githubusercontent.com/naptha/tesseract.js/master/tests/assets/images/bill.png"
  ],
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call fabrikit/image-ocr-extractor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,fabrikit/image-ocr-extractor"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/92kCsHc4aGx6sFNnt/builds/VrX6WoAY3OwCUURZd/openapi.json
