# Image to Text OCR — Extract Text from Images (`junipr/image-to-text`) Actor

Extract text from images with OCR, confidence scores, language options, page/image metadata, and automation-ready text exports.

- **URL**: https://apify.com/junipr/image-to-text.md
- **Developed by:** [junipr](https://apify.com/junipr) (community)
- **Categories:** Automation, Developer tools
- **Stats:** 34 total users, 9 monthly users, 95.9% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$6.50 / 1,000 image ocrs

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Image to Text OCR — Extract Text from Images

### Introduction

Extract text from images using Tesseract OCR — fully self-contained, no external API keys required. This actor processes single images or batches of up to 500, returning clean extracted text with confidence scores at the word, line, and block level. Supported formats include JPEG, PNG, WebP, TIFF, BMP, and GIF.

**Primary use cases:** document digitization, receipt and invoice processing, screenshot text extraction, product label reading, and automated data entry from image-based sources.

**Key differentiators:** 100+ languages supported out of the box, word-level confidence scoring and bounding boxes for spatial analysis, automatic image preprocessing (deskew, contrast enhancement, binarization) for improved accuracy on low-quality scans, and zero infrastructure setup — just provide image URLs.

***

### Why Use This Actor

**No external API key required.** Unlike Google Vision or AWS Textract, this actor uses Tesseract.js — a fully self-contained WASM OCR engine. There's no GCP project, no AWS account, no credit card required beyond your Apify plan.

**Cost comparison:** At $6.50 per 1,000 images in the live Store pricing entry, this actor is simpler to use than Google Vision or AWS Textract because it needs no separate cloud account, API key, or provider billing setup.

**100+ languages included.** Most online OCR tools support 25 or fewer languages. This actor ships with Tesseract's full language library — including CJK scripts (Chinese, Japanese, Korean), Arabic, Hindi, and dozens of European languages. Multi-language documents (e.g., `eng+fra`) are supported in a single run.

**Structured output with confidence filtering.** Get word-level confidence scores and pixel-accurate bounding boxes. Filter out low-confidence words automatically using `minConfidence`. Use bounding boxes to reconstruct document layout or extract specific regions.

**Auto preprocessing improves accuracy.** The actor automatically resizes small images, enhances contrast, binarizes, and corrects EXIF orientation before OCR. This produces noticeably better results on scanned documents, screenshots, and photos taken in poor lighting — without any manual image editing.

***

### How to Use

**Zero-config example:** Provide an array of image URLs and the actor will extract text using English OCR with preprocessing enabled.

```json
{
  "images": [
    { "url": "https://example.com/invoice.jpg" },
    { "url": "https://example.com/receipt.png" }
  ]
}
```

**Japanese text extraction:**

```json
{
  "images": [{ "url": "https://example.com/japanese-doc.jpg" }],
  "language": "jpn",
  "outputLevel": "full"
}
```

**Calling via Apify API (Node.js):**

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

const client = new ApifyClient({ token: 'YOUR_TOKEN' });
const run = await client.actor('junipr/image-to-text').call({
  images: [{ url: 'https://example.com/image.png' }],
  language: 'eng',
  outputLevel: 'text',
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items[0].text);
```

**Filtering low-confidence results:** Set `minConfidence: 70` to only keep words the OCR engine is confident about. Useful for noisy or degraded images where some text is too blurry to read reliably.

***

### Input Configuration

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `images` | array | required | Array of `{url}` or `{kvStoreKey}` objects. Max 500. |
| `language` | string | `"eng"` | Tesseract language code. Use `"eng+fra"` for multiple. |
| `ocrEngine` | string | `"lstm"` | `"lstm"` (best), `"legacy"` (faster), `"combined"` (highest quality). |
| `pageSegMode` | integer | `3` | Page segmentation mode. 3=auto, 6=block, 7=line, 11=sparse. |
| `whitelist` | string | — | Only recognize these characters (e.g. digits for receipts). |
| `blacklist` | string | — | Never output these characters. |
| `preprocess` | boolean | `true` | Enable auto image preprocessing for better accuracy. |
| `enhanceContrast` | boolean | `true` | Normalize image contrast. |
| `binarize` | boolean | `true` | Convert to black and white before OCR. |
| `scale` | number | auto | Scale factor (0.5–4.0). Auto-scales small images. |
| `denoise` | boolean | `false` | Apply median denoising for scanned images. |
| `outputLevel` | string | `"text"` | `"text"`, `"lines"`, `"words"`, or `"full"` (with bounding boxes). |
| `minConfidence` | integer | `0` | Exclude words below this confidence (0–100). |
| `includeRawHocr` | boolean | `false` | Include raw hOCR XML in output (requires `outputLevel: "full"`). |
| `maxConcurrency` | integer | `2` | Max simultaneous OCR operations (1–5). |
| `imageTimeout` | integer | `30000` | Image download timeout in ms. |
| `ocrTimeout` | integer | `60000` | OCR processing timeout per image in ms. |

**Common configurations:**

*Quick text extraction (defaults):*

```json
{ "images": [{ "url": "..." }] }
```

*High-quality OCR with bounding boxes:*

```json
{ "images": [{ "url": "..." }], "outputLevel": "full", "preprocess": true, "denoise": true }
```

*Numbers only (receipts, invoices):*

```json
{ "images": [{ "url": "..." }], "whitelist": "0123456789.$,", "pageSegMode": 6 }
```

*Multi-language document:*

```json
{ "images": [{ "url": "..." }], "language": "eng+fra+deu" }
```

***

### Output Format

**Text-level output (`outputLevel: "text"`):**

```json
{
  "sourceUrl": "https://example.com/invoice.jpg",
  "sourceKvKey": null,
  "text": "Invoice #12345\nDate: January 15, 2025\nTotal: $248.50",
  "language": "eng",
  "confidence": 94.2,
  "wordCount": 9,
  "lineCount": 3,
  "blockCount": 2,
  "imageWidth": 1200,
  "imageHeight": 800,
  "preprocessed": true,
  "processingTimeMs": 1840,
  "processedAt": "2025-01-15T12:00:00.000Z",
  "errors": []
}
```

**Full output (`outputLevel: "full"`) — includes bounding boxes:**

```json
{
  "sourceUrl": "https://example.com/doc.png",
  "text": "Hello World",
  "confidence": 96.5,
  "wordCount": 2,
  "blocks": [
    {
      "text": "Hello World",
      "confidence": 96.5,
      "bbox": { "x0": 10, "y0": 20, "x1": 200, "y1": 50 },
      "paragraphs": [
        {
          "text": "Hello World",
          "confidence": 96.5,
          "bbox": { "x0": 10, "y0": 20, "x1": 200, "y1": 50 },
          "lines": [
            {
              "text": "Hello World",
              "confidence": 96.5,
              "bbox": { "x0": 10, "y0": 20, "x1": 200, "y1": 50 },
              "words": [
                { "text": "Hello", "confidence": 97.1, "bbox": { "x0": 10, "y0": 20, "x1": 90, "y1": 50 } },
                { "text": "World", "confidence": 95.9, "bbox": { "x0": 100, "y0": 20, "x1": 200, "y1": 50 } }
              ]
            }
          ]
        }
      ]
    }
  ],
  "ocrEngineUsed": "lstm",
  "hocr": null,
  "processedAt": "2025-01-15T12:00:00.000Z",
  "errors": []
}
```

**Confidence scores** range from 0 (no confidence) to 100 (very high confidence). Scores above 85 indicate reliable OCR on clear printed text. Scores below 50 suggest blurry, degraded, or handwritten input.

**Run summary** is stored in the key-value store under the `OUTPUT` key and includes total images processed, success/failure counts, total words extracted, average confidence, and total duration.

***

### Tips and Advanced Usage

**Improving accuracy on blurry or faded images:** Enable all preprocessing options (`preprocess: true`, `enhanceContrast: true`, `binarize: true`, `denoise: true`). For very small text, set `scale: 2.0` to double the image size before OCR.

**Extracting data from receipts and invoices:** Use `whitelist: "0123456789.$,."` combined with `pageSegMode: 6` (single block) to extract numbers only. This dramatically reduces misrecognized characters in numerical fields.

**Handling rotated or tilted documents:** Set `pageSegMode: 1` (auto with orientation detection). Tesseract's OSD (Orientation and Script Detection) will automatically detect and correct orientation before OCR.

**Processing screenshots with UI elements:** The `full` output level preserves spatial layout via bounding boxes. You can filter extracted text by pixel coordinates to isolate specific UI regions without manual cropping.

**CJK languages (Chinese, Japanese, Korean):** Use `language: "chi_sim"` for Simplified Chinese, `"chi_tra"` for Traditional Chinese, `"jpn"` for Japanese, or `"kor"` for Korean. CJK language data files are larger (~15 MB), so the first run may be slightly slower while they download and cache.

**Building document processing pipelines:** Combine this actor with the [PDF to Text Extractor](https://apify.com/junipr/pdf-to-text-extractor) for complete document coverage. Use image OCR for scanned PDFs and photos; use PDF to Text for digital PDFs.

**Multi-language documents:** Specify multiple languages as a `+`-separated string: `"eng+fra"`, `"eng+deu+fra"`. Tesseract loads all specified language models and attempts to recognize text in any of them. Performance decreases with more languages loaded simultaneously.

***

### Pricing

This actor uses Pay-Per-Event pricing with the `image-ocr` event: **$6.50 per 1,000 images** processed ($0.0065 per image) in the live Store pricing entry.

Apify platform usage follows the live Store pricing entry.

A billable event is charged when: the image downloads successfully AND OCR processing completes (even if no text is found — processing still occurred). Images that fail to download or are invalid are **not billed**.

| Volume | Estimated Cost |
|--------|---------------|
| 1 image | $0.0065 |
| 50 images (receipt batch) | $0.33 |
| 500 images (document scan) | $3.25 |
| 5,000 images (archive) | $32.50 |
| 50,000 images (enterprise) | $325.00 |

**Comparison:**

- Google Vision API: ~$1.50/1K (but requires GCP account and setup)
- AWS Textract: ~$1.50/1K (requires AWS account, complex setup)
- OCR.space: $3+/1K (25 languages only, no bounding boxes)
- This actor: $6.50/1K (no setup, 100+ languages, word-level bounding boxes)

***

### FAQ

#### What languages are supported?

Over 100 languages via Tesseract's language data files. Common codes: `eng` (English), `fra` (French), `deu` (German), `spa` (Spanish), `ita` (Italian), `por` (Portuguese), `chi_sim` (Simplified Chinese), `chi_tra` (Traditional Chinese), `jpn` (Japanese), `kor` (Korean), `ara` (Arabic), `hin` (Hindi), `rus` (Russian). Full list available at the [Tesseract language data repository](https://tesseract-ocr.github.io/tessdoc/Data-Files).

#### How accurate is the OCR?

On clear, well-formatted printed text (documents, invoices, books), expect confidence scores above 85% and near-perfect extraction. On photos with text overlaid on complex backgrounds, poor lighting, or significant compression artifacts, accuracy decreases. Enable all preprocessing options for best results. CJK scripts and cursive fonts are harder for Tesseract than Latin scripts.

#### Can it read handwritten text?

Partially. Tesseract's LSTM engine handles basic block-letter handwriting but is not specialized for cursive or varied handwriting styles. Confidence scores will be lower (often below 50) for handwritten input. For dedicated handwriting recognition, consider Google Vision or Azure Computer Vision.

#### What image formats are supported?

JPEG, PNG, WebP, TIFF, BMP, and GIF. Animated GIFs are supported — only the first frame is processed. Very large images (over 4,000 pixels on the longest side) are automatically resized to conserve memory.

#### How do I improve accuracy on blurry images?

Enable all preprocessing: `preprocess: true`, `enhanceContrast: true`, `binarize: true`, `denoise: true`. Increase scale with `scale: 2.0` or `scale: 3.0` for very small text. Try `ocrEngine: "combined"` for the highest accuracy (slowest). If possible, source higher-resolution images before running OCR.

#### Can I extract text from PDFs?

Not with this actor. PDFs (both digital and scanned) are handled by the companion [PDF to Text Extractor](https://apify.com/junipr/pdf-to-text-extractor) actor. If you provide a `.pdf` URL here, the actor will return a clear error directing you to the correct tool.

#### What do the confidence scores mean?

Tesseract returns a confidence percentage (0–100) for each recognized word and for the overall document. Above 85 = reliable printed text. 60–85 = acceptable for most documents. 30–60 = degraded image or complex layout. Below 30 = likely handwriting, noise, or very poor quality. Use `minConfidence` to exclude low-confidence words from output.

#### Does it detect text orientation automatically?

Yes, when `pageSegMode` is set to `1` (Auto with OSD). The default mode `3` (fully automatic) handles moderate rotation but may miss severe rotation. For images known to be rotated 90° or 180°, set `pageSegMode: 1` explicitly. EXIF-based rotation is also corrected automatically during preprocessing.

***

### Related Actors

- [PDF to Text Extractor](https://apify.com/junipr/pdf-to-text-extractor) — Extract text from PDF files (digital and scanned)
- [Document Format Converter](https://apify.com/junipr/document-format-converter) — Convert between document formats
- [Web Page Change Monitor](https://apify.com/junipr/web-page-change-monitor) — Monitor web pages for content changes
- [Multi-Resolution Screenshot](https://apify.com/junipr/multi-resolution-screenshot) — Capture screenshots at multiple viewport sizes

# Actor input Schema

## `images` (type: `array`):

List of images to process. Each entry must have either a 'url' (image URL) or 'kvStoreKey' (key in the actor's key-value store). Minimum 1, maximum 500.

## `language` (type: `string`):

Tesseract language code for OCR. Common codes: 'eng' (English), 'fra' (French), 'deu' (German), 'spa' (Spanish), 'chi\_sim' (Simplified Chinese), 'jpn' (Japanese), 'kor' (Korean), 'ara' (Arabic). Combine multiple: 'eng+fra'. Full list at https://tesseract-ocr.github.io/tessdoc/Data-Files.

## `ocrEngine` (type: `string`):

OCR engine mode. 'lstm' uses the neural network engine for best accuracy. 'legacy' uses the traditional engine — faster but less accurate. 'combined' uses both for highest accuracy but slowest speed.

## `pageSegMode` (type: `integer`):

Controls how Tesseract segments the image. 3 (auto) works for most images. Use 6 for single text blocks, 7 for single lines, 8 for single words, 11 for sparse text, 1 for auto with orientation detection (good for rotated text).

## `whitelist` (type: `string`):

Only recognize these characters. Useful for extracting specific data types. Example: '0123456789.$,' for receipt amounts only. Leave empty to recognize all characters.

## `blacklist` (type: `string`):

Never output these characters. Ignored if a whitelist is also specified.

## `preprocess` (type: `boolean`):

Enable automatic image preprocessing (deskew, contrast enhancement, binarization) for improved OCR accuracy. Recommended for most images, especially scanned documents.

## `deskew` (type: `boolean`):

Correct image rotation based on EXIF orientation data. Only applies when preprocessing is enabled.

## `enhanceContrast` (type: `boolean`):

Normalize image histogram to enhance contrast for faded or low-contrast text. Only applies when preprocessing is enabled.

## `binarize` (type: `boolean`):

Convert image to black and white using thresholding. Improves OCR on images with complex backgrounds. Only applies when preprocessing is enabled.

## `scale` (type: `number`):

Scale the image before OCR. 2.0 doubles the size (improves accuracy on small text). Leave empty for auto-scaling (doubles if image width < 800px). Min: 0.5, Max: 4.0.

## `denoise` (type: `boolean`):

Apply median denoising filter for noisy or scanned images. Adds extra processing time. Recommended for low-quality scans.

## `outputLevel` (type: `string`):

Detail level of OCR output. 'text' returns plain extracted text only. 'lines' adds line-level confidence scores. 'words' adds word-level positions and confidence. 'full' includes complete structure with bounding boxes for blocks, paragraphs, lines, and words.

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

Minimum OCR confidence threshold (0-100). Words with confidence below this value are excluded from output. 0 includes all results. 70 keeps only high-confidence text.

## `includeRawHocr` (type: `boolean`):

Include the raw hOCR XML output from Tesseract in the 'hocr' field. hOCR contains full positional data in standard XML format for advanced processing. Only available with outputLevel 'full'.

## `stripExtraWhitespace` (type: `boolean`):

Collapse multiple consecutive spaces and newlines into single characters. Cleans up common OCR artifacts for cleaner output.

## `maxConcurrency` (type: `integer`):

Maximum number of images processed simultaneously. Tesseract is CPU-intensive — keep this low (2-3) to avoid memory issues on large batches. Min: 1, Max: 5.

## `imageTimeout` (type: `integer`):

Timeout in milliseconds for downloading each source image. Increase for slow servers or large images. Min: 5000, Max: 120000.

## `ocrTimeout` (type: `integer`):

Timeout in milliseconds for OCR processing per image. Increase for very complex, high-resolution images. Min: 10000, Max: 300000.

## Actor input object example

```json
{
  "images": [
    {
      "url": "https://placehold.co/1200x320/FFFFFF/000000/png?text=JUNIPR+OCR+READY"
    }
  ],
  "language": "eng",
  "ocrEngine": "lstm",
  "pageSegMode": 3,
  "preprocess": true,
  "deskew": true,
  "enhanceContrast": true,
  "binarize": true,
  "denoise": false,
  "outputLevel": "text",
  "minConfidence": 0,
  "includeRawHocr": false,
  "stripExtraWhitespace": true,
  "maxConcurrency": 1,
  "imageTimeout": 30000,
  "ocrTimeout": 60000
}
```

# Actor output Schema

## `results` (type: `string`):

OCR results for each processed image including extracted text, confidence scores, and optional bounding boxes

# 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 = {
    "maxConcurrency": 1
};

// Run the Actor and wait for it to finish
const run = await client.actor("junipr/image-to-text").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 = { "maxConcurrency": 1 }

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

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

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

```

## CLI example

```bash
echo '{
  "maxConcurrency": 1
}' |
apify call junipr/image-to-text --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=junipr/image-to-text",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/acts/E8So9WOZrrl7lfxY8/builds/oL5Lh8TsnATSjVqoi/openapi.json
