Image OCR: Image to Text, Arabic and 120 Languages
Pricing
from $2.40 / 1,000 image reads
Image OCR: Image to Text, Arabic and 120 Languages
OCR for images: extract text from photos, screenshots and scanned pages with Tesseract. Bulk input from URLs or another Actor's dataset. Returns text, confidence, lines and optional word boxes or hOCR. Arabic right-to-left, English and 120 more languages. No outside OCR API.
Pricing
from $2.40 / 1,000 image reads
Rating
0.0
(0)
Developer
Malik Said
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
13 hours ago
Last modified
Categories
Share
Extract text from images and PDF files with Tesseract OCR. You give image or PDF URLs, a CSV or Google Sheets list of links, a dataset or a key-value store. You get one row per image or PDF page with the text, a confidence score and the text lines. Word boxes, hOCR and Markdown are optional.
Arabic, English and about 120 more languages work. Arabic and other right-to-left text comes out in reading order. OCR runs inside the Actor. Images never leave the run: no image is sent to an outside OCR service.
What you get
Each row holds:
text: all text in the image, line by line.confidence: mean word confidence from 0 to 100.lowConfidenceis true when it is under 60.droppedWordCount: words left out by Minimum word confidence.lines: each line with its text, confidence, reading direction (ltrorrtl) and bounding box.words(optional): each word with its confidence and bounding box in pixels.paragraphs(optional): each paragraph with its text, confidence, reading direction and bounding box.hocr(optional): hOCR HTML with the full layout.markdown(optional): paragraphs in reading order, ready for an AI model or a search index. PDF pages start with## Page N.preprocess: the cleaning step used before OCR.- PDF pages:
pageNumber,pageCountandtextSource(ocr, ortext_layerwhen the page's own text was copied). sourceItem(optional): the dataset row or list row the image came from, so the text lines up with your own columns.mainScriptanddirection: the main writing system found (for example Latin or Arabic) and whether the page reads left to right, right to left or mixed.- Image facts: format, width, height and file size.
source:url,keyValueStore,dataset,base64orlist. Rows from a list file carrylistRowIndex. Rows from a dataset also carrydatasetIdanddatasetItemIndex(the row's position, from 0). Base64 rows carrybase64Index.statusanderror: images that cannot be read get a row with the reason. They are not charged.
Use cases
- Read scanned letters, forms, receipts and invoices in bulk.
- Make screenshots and photos of signs searchable.
- Read Arabic and English documents from the Gulf and the Middle East.
- Feed image text into search, translation or an AI pipeline.
Input
| Field | What it does |
|---|---|
| Image URLs | Links to images or PDF files, one per line. PNG, JPEG, WebP, BMP, GIF, TIFF, PNM and PDF work |
| Image list file | A link to a CSV or text file with image links, for example a Google Sheets CSV export. Every cell that starts with http is one image |
| Key-value store with image files | Pick one of your stores. The Actor reads every image record, or only the keys you list. It only reads the store |
| Dataset with image links | Pick a dataset, for example the output of another scraper. The Actor reads the image link from each row. It only reads the dataset |
| Link field in the dataset | The field with the link, for example imageUrl or images.0. Empty: the first of url, imageUrl, image, src, displayUrl, thumbnailUrl with a link. A list of links gives one image each |
| Keep the source row | Copies the dataset or list row into sourceItem (up to 10 KB) |
| Images as base64 | Images as base64 text or data URLs, for images with no public link. Up to 8 MB of base64 text per run. Each row gets base64Index |
| Maximum PDF pages | Pages read per PDF. Default 10. Set 0 for every page |
| PDF render DPI | Resolution for scanned pages. Default 150 |
| Use the PDF's own text | Copies the text of digital pages as is, without OCR. Default on |
| Languages | Every language in the images. Use English and Arabic for bilingual documents. Default: English |
| Model | Fast (default) or Accurate. Accurate is a little better and about 1.6 times slower |
| Page layout | Automatic, single column, single block, single line, single word or sparse text |
| Keep spaces between words | Keeps table-like layouts aligned in each line |
| Clean images before OCR | Off, Auto, Grayscale or Black and white. Auto fixes transparent images and enlarges small text |
| Minimum word confidence | Drops weaker words from text, lines, words and paragraphs. Default 0 keeps every word |
| Include lines, word boxes, paragraphs, hOCR, Markdown | Choose how much layout data each row carries |
| Maximum image size | Skips files above this size. Default 20 MB |
| Maximum images | Stops after this many images. Default 100. Set 0 for no limit |
Example input:
{"imageUrls": ["https://upload.wikimedia.org/wikipedia/commons/5/50/Double_sentence-spaced_typewriter_text_vs._single-spaced_printed_text.jpg"],"languages": ["eng", "ara"],"includeWords": false}
Example input for an image you hold in memory, with cleaning and a word filter:
{"imagesBase64": ["data:image/png;base64,iVBORw0KGgo..."],"preprocess": "auto","minWordConfidence": 60,"includeParagraphs": true}
Example input that reads images another Actor scraped:
{"datasetId": "YOUR_DATASET_ID","datasetUrlField": "imageUrl","languages": ["eng"]}
Output example
This row comes from a test image with Arabic and English text, read with languages ara and eng. Lines and words are shortened.
{"status": "ok","source": "keyValueStore","keyValueStoreKey": "ar-udhr","format": "png","imageWidth": 800,"imageHeight": 400,"languages": ["ara", "eng"],"model": "fast","text": "يولد جميع الناس أحراراً متساوين في الكرامة والحقوق. وقد وهبوا عقلاً\nوضميراً وعليهم أن يعامل بعضهم بعضاً بروح الإخاء.\n\nفاتورة رقم 2048 بتاريخ 21 أكتوبر 2026. المبلغ الإجمالي 1,250 ريال.\n\nInvoice total: SAR 1,250. Thank you.","confidence": 91,"lowConfidence": false,"droppedWordCount": 0,"mainScript": "Arabic","direction": "mixed","wordCount": 36,"lineCount": 4,"lines": [{"text": "فاتورة رقم 2048 بتاريخ 21 أكتوبر 2026. المبلغ الإجمالي 1,250 ريال.","confidence": 93,"direction": "rtl","bbox": { "x0": 85, "y0": 139, "x1": 770, "y1": 171 }}],"words": [{ "text": "يولد", "confidence": 92, "bbox": { "x0": 737, "y0": 37, "x1": 770, "y1": 62 }, "lineIndex": 0 }]}
OCR images from a spreadsheet
Keep your image links in Google Sheets? Publish the sheet as CSV (File > Share > Publish to web > CSV) and paste the link in Image list file. Turn on Keep the source row to get each row's other columns, such as a SKU, next to its text.
{"imageListUrl": "https://docs.google.com/spreadsheets/d/e/YOUR_SHEET/pub?output=csv","keepSourceFields": true,"includeMarkdown": true}
Use it from the API or an AI agent
Send base64 images and get the text back in one call:
curl -X POST "https://api.apify.com/v2/acts/maliksaid~image-ocr-text-extractor/run-sync-get-dataset-items?token=YOUR_TOKEN" \-H "Content-Type: application/json" \-d '{"imagesBase64": ["data:image/png;base64,iVBORw0KGgo..."], "includeMarkdown": true}'
AI agents can call this Actor through the Apify MCP server (mcp.apify.com) with the same input.
Pricing
You pay per image read, plus a small fee per run.
Each PDF page counts as one image. The start fee is charged once per GB of memory (the default is 1 GB).
| Event | Free plan | GOLD plan and higher |
|---|---|---|
| Run start | $0.002 | $0.002 |
| Image read | $0.003 ($3.00 per 1,000) | $0.0024 ($2.40 per 1,000) |
| Images in one run | Free plan | GOLD plan and higher |
|---|---|---|
| 100 | $0.302 | $0.242 |
| 1,000 | $3.002 | $2.402 |
Costs include the run start fee.
- Images that fail (not found, not an image, blocked by robots.txt) are saved with the reason and not charged.
Platform usage is included in the price.
Speed
One page-sized scan takes about 2 to 20 seconds at the default 1 GB of memory. Apify gives more CPU to more memory, so 2 GB should be about twice as fast. The price per image stays the same. The default timeout is one hour.
Tips for good results
- List every language in the image. Tesseract does not guess the language. The
mainScriptfield helps you pick the right one. - More languages make OCR slower. Use only the ones you need.
- Text should be at least about 20 pixels high. Very small or blurred text gives low confidence.
- Use "Sparse text" for photos, signs and screenshots with scattered words.
- Transparent images, photos and small text read better with Clean images before OCR set to Auto.
- Every row has
lowConfidence. Use it to find weak images fast, and Minimum word confidence to drop noise words. - Handwriting is not supported well. Tesseract reads printed text.
Responsible use
- The Actor only reads the images you list. It reads robots.txt on each host first and skips images that it does not allow.
- It does not log in anywhere and does not pass CAPTCHAs.
- Make sure you have the right to process the images you submit, especially images with personal data.
Engine and licences
- OCR engine: Tesseract 5 through tesseract.js 7.0.0 (Apache-2.0).
- PDF reading: pdf.js 6.4.299 (Apache-2.0) and @napi-rs/canvas 1.0.10 (MIT).
- Language models: the official Tesseract repositories tessdata_fast and tessdata (Apache-2.0), at pinned versions.
FAQ
Can it read PDFs? Yes. Scanned and digital PDFs are read page by page, one row per page, up to Maximum PDF pages (default 10). Digital pages are copied from the PDF's own text. Password-protected PDFs are skipped free.
Is my image sent to another service? No. Tesseract runs inside the Actor. Images and PDFs are read only inside your run.
Can I OCR the images another Actor scraped? Yes. Pick that run's dataset in "Dataset with image links". Name the link field, or leave it empty to detect it. Each row's datasetItemIndex points back to the source row.
Which language codes can I use? The Languages list in the input shows all of them, for example eng English, ara Arabic, fas Persian, urd Urdu, fra French and chi_sim Chinese.
Why is a row's status "failed"? The error field says why: for example HTTP 404, a file that is not an image, or a host whose robots.txt does not allow the URL.