BlogProduction workflows7 min read
Check the scans of an Arabic book before you run OCR
Before you OCR a scanned Arabic book, check every page: at least 300 ppi, grayscale rather than black-and-white, one page per image, not stretched. Poppler's pdfimages lists this per page in seconds. Rescan the pages that fail if you can, because enlarging a scan later cannot restore dots and vowel marks.
Most problems in an OCR'd Arabic book start before the OCR. A few pages were scanned at low resolution, the scanner was left on black-and-white, or two facing pages were captured as one image. Nothing looks wrong at a glance, and you only notice later: a page with more misread letters than the rest, or vowel marks that disappear halfway through a chapter.
This guide is for anyone about to send a whole book through OCR: an editor or researcher digitizing a printed edition, a publisher converting a backlist, or a document-service team receiving scans from a client. It shows how to check every page of the PDF you already have in a minute or two, what each problem means, and which settings to use when you rescan.
Why Arabic is less forgiving
In Arabic, small marks carry meaning. Dots alone separate ب, ت, ث, ن and ي, and in a vocalized text a fatha, kasra or shadda can change the reading of a word. These marks are a fraction of the size of the letters around them, so they are the first thing a poor scan loses.
You can estimate how many pixels a mark gets: pixels = size in points ÷ 72 × ppi (pixels per inch).
Illustrative example. Suppose a vowel mark in a printed book is about 1 point across (a round figure for the arithmetic, not a measurement). At 300 ppi it gets about 4 pixels; at 150 ppi, about 2. A black-and-white scan has to decide whether each of those few pixels is black or white, so a faint mark can vanish completely.
What OCR vendors recommend
Two widely used OCR tools publish scanning advice, and it agrees:
- Tesseract's documentation says it "works best on images which have a DPI of at least 300 dpi". It also warns that dark scanner borders can be picked up as extra characters, that skew hurts line detection, and that its own binarisation (turning the image into black and white) "can be suboptimal, particularly if the page background is of uneven darkness".
- ABBYY's FineReader guide recommends scanning at 300 dpi, says that less than 150 dpi "adversely affects OCR quality" and that more than 600 dpi slows OCR down, calls grayscale "the best mode for OCR", and says images with facing pages should be split into two.
These are general guidelines, not Arabic-specific ones. They give a sensible floor, and the sample-page test below tells you whether your particular book needs more.
Step 1: list the images in the PDF
A scanned PDF is a stack of page images. Poppler's pdfimages tool (free; part of
poppler-utils on Linux, and available through Homebrew on macOS and as a Windows build) can
list them without extracting anything:
pdfimages -list book.pdf
Each row is one image. The columns that matter here:
| Column | What it tells you |
|---|---|
| page | which page the image is on |
| width, height | the image size in pixels |
| color | gray, rgb, cmyk or index |
| bpc | bits per component: 1 means pure black-and-white, 8 means grayscale or colour |
| enc | how the image is compressed (jpeg, ccitt, image, and so on) |
| x-ppi, y-ppi | the resolution of the image as placed on the PDF page |
Rows typed smask or mask are transparency masks, not page scans, so ignore them.
Step 2: check every page with a short script
On a 400-page book, reading that table by eye is slow. This Python 3 script runs pdfimages
and pdfinfo, takes the largest image on each page and flags the problems described below:
"""Report the scan resolution and colour of every page in a PDF.
Usage: python3 check_scan.py book.pdf
Needs Poppler's pdfimages and pdfinfo on the PATH.
"""
import subprocess
import sys
pdf = sys.argv[1]
info = subprocess.run(["pdfinfo", pdf], capture_output=True, text=True).stdout
pages = int(next(l.split()[-1] for l in info.splitlines() if l.startswith("Pages:")))
listing = subprocess.run(["pdfimages", "-list", pdf], capture_output=True, text=True).stdout
largest = {}
for line in listing.splitlines()[2:]:
f = line.split()
if len(f) < 14 or f[2] != "image":
continue
page, w, h = int(f[0]), int(f[3]), int(f[4])
if page not in largest or w * h > largest[page]["area"]:
largest[page] = dict(area=w * h, w=w, h=h, color=f[5], bpc=int(f[7]),
enc=f[8], xppi=int(f[12]), yppi=int(f[13]))
for p in range(1, pages + 1):
im = largest.get(p)
if im is None:
print(f"page {p}: no image (typed or blank page?)")
continue
notes = []
low = min(im["xppi"], im["yppi"])
if low < 300:
notes.append(f"LOW {low} ppi")
if low > 600:
notes.append("over 600 ppi")
if abs(im["xppi"] - im["yppi"]) > 0.05 * low:
notes.append("stretched")
if im["bpc"] == 1:
notes.append("black-and-white")
if im["w"] > 1.2 * im["h"]:
notes.append("wide: two facing pages?")
print(f"page {p}: {im['xppi']}x{im['yppi']} ppi, {im['color']} {im['bpc']}-bit, "
f"{im['enc']} " + ("; ".join(notes) or "ok"))
Save the output next to the book. If the file came from a client, it is a factual record of what you received.
What we ran while writing this guide
We generated seven small test PDFs with ImageMagick and ran the script on each (Python 3.11, Poppler 24.02). The pages held blank grey images, not real book scans, because the test was about what the script reports, not about OCR:
| Test file | Script output |
|---|---|
| one page, 300 ppi grayscale | ok |
| one page, 150 ppi grayscale | LOW 150 ppi |
| one page, 300 ppi black-and-white (CCITT) | black-and-white |
| two facing pages in one 300 ppi image | wide: two facing pages? |
| three JPEG pages, the middle one at 200 ppi | page 2 flagged LOW 200 ppi; pages 1 and 3 ok |
| 300 ppi scan plus one typed (vector text) page | page 2: no image |
| image placed at 300 × 200 ppi | LOW 200 ppi; stretched |
We did not OCR these files, and we did not test ScribeTools or any other OCR tool with them.
Step 3: decide what to do with each flag
LOW ppi. If you still have the book, rescan those pages. A tool can enlarge a low-resolution image, but it cannot restore a dot or vowel mark the scanner never captured clearly. If rescanning is impossible (a borrowed copy, a rare edition), keep the pages and plan for more proofreading on them: list them in your delivery note so the reviewer knows where to look.
black-and-white. A 1-bit scan has already made the black-or-white decision for every pixel, which is where faint marks get lost. Rescan in grayscale if you can. If not, zoom to 400% on a page with dense vocalization and check whether the marks are still whole.
wide: two facing pages? Split each image into two pages before OCR, as ABBYY advises. Otherwise lines from the right and left pages can be read as one line, which in a right-to-left book scrambles the reading order.
stretched. The horizontal and vertical resolutions differ, so the letters are squashed. This usually comes from a scanner setting or a converter. Re-export or rescan at equal resolution.
over 600 ppi. Not a quality problem. The file is large and processing is slower. There is no need to rescan.
no image. The page holds typed text or nothing at all. It may already have real text, so check it the way described in how to check that a searchable Arabic PDF really works.
Rescan settings checklist
- Resolution: 300 ppi at least. For very small print or dense vocalization, scan one test page at 400 and 600 ppi and compare at 400% zoom before choosing.
- Colour mode: grayscale. Use colour only where colour carries meaning (rubrication, coloured headings, stamps).
- One page per image: split facing pages, or scan each page separately.
- Flat pages: press the gutter down so lines near the spine do not curve or darken.
- Straight lines: correct skew so text lines are horizontal.
- Borders: crop dark scanner edges, but leave a small white margin around the text.
- Brightness: avoid both washed-out and heavy, blotted strokes. ABBYY notes that its 50% setting works in most cases.
- Same settings for the whole book, so one chapter does not behave differently from the rest.
- Run the script again on the new PDF before you send it anywhere.
Phone photos
Photos of pages have no meaningful ppi of their own, so pdfimages numbers depend on the page
size the converting app chose. Instead, divide the photo's width in pixels by the page's
real width in inches. A 6-inch-wide page photographed 3,000 pixels across works out at about
500 ppi; the same page at 1,200 pixels is about 200 ppi. Fill the frame with one page, hold the
phone parallel to the page, and use even light without shadows across the text.
Test a sample before the whole book
Before processing hundreds of pages, run three or four hard pages first: the densest vocalization, a page of footnotes, the faintest print and a page from the inner margin. Compare the output with the scan at high zoom. If those pages come out well, you have less reason to expect surprises elsewhere. If they do not, fix the scans now, not after the whole book has been processed and proofread.
ScribeTools accepts scanned PDFs and images, so this sample can run on the free pages every account starts with. See digitizing Arabic books for the whole job, and how to convert a scanned Arabic book to Word for the short version. Once the text is out, the pre-delivery checks for an OCR'd Arabic Word file pick up where this guide ends.
Limitations
x-ppiandy-ppidescribe the image as placed on the PDF page. If a converter set an odd page size, the numbers stop matching the original scan resolution. Compare the PDF page size (frompdfinfo) with the real book if a value looks suspicious.- The script reads only the largest image on each page. It does not measure blur, contrast, skew, show-through from the other side of the paper, or how heavily JPEG compression has damaged fine marks. Look at a few pages at high zoom as well.
- 300 ppi is the floor that Tesseract and ABBYY recommend, not a guarantee. A clean 300 ppi scan of worn type can still produce errors, and every OCR output should be reviewed before anyone relies on it.
- Our test files were synthetic, as described above. We did not measure how resolution or colour mode changes the results of any OCR tool.