Someone hands you a strip of paper that was a receipt six months ago and is now a blank curl with a grey shadow at the top. Before you spend a week on image processing, it is worth knowing exactly what happened to it, because it decides what is possible.
Why thermal paper goes blank
Direct thermal paper has no ink and no ribbon. It is coated with two chemicals held apart in a solid matrix: a colourless dye precursor — a leuco dye — and an acidic developer, historically a bisphenol. The print head heats a dot to the melting point of the matrix, the two chemicals mix at that spot, the dye takes its coloured form, and the spot goes dark as the matrix re-solidifies.
Everything about the medium’s fragility follows from that. The reaction is reversible: heat the whole sheet and it turns uniformly black, then, past a point, back to nothing. The developer is mobile: plasticisers in a PVC wallet, oils from skin, alcohol from hand sanitiser, and the adhesive on tape will all dissolve or migrate it out of the imaged area. Ultraviolet light degrades the coloured form directly. And there is no physical impression — nothing was pressed into the paper, nothing was deposited on it.
That last point is the one that matters here. On an impact-printed multipart form, a carbonless copy leaves a physical dent you can light obliquely and recover. On a faded thermal receipt the printed information does not exist anywhere in the physical object any more. It is not hidden under noise. It is gone.
This is not an OCR settings problem
This is where the page diverges from extracting from a blurry photo, and the distinction is worth being precise about because the two arrive at the same helpdesk. In a blurry photo the information is present in the image and spread across neighbouring pixels — degraded, but there, which is why de-warping, thresholding and a tighter crop genuinely recover fields. On faded thermal stock there is nothing to spread; contrast enhancement amplifies paper texture and scanner noise into shapes that look like glyphs.
Which is why the two worst things you can do here are the two most commonly suggested. A generative upscaler will invent a total. It will be crisp, it will be well-formed, it will have a plausible number of digits, and there is no signal anywhere in your pipeline that distinguishes it from a real reading. And gently heating the receipt to “bring the print back” — a widely repeated trick — darkens the entire coating uniformly, which destroys whatever contrast was left and is not reversible. If you are going to try that, photograph the receipt first.
What genuinely recovers contrast
There is a real gap between a phone snapshot of a faded receipt and the best image obtainable from it, and closing that gap is worth doing before deciding a field is unrecoverable.
- Scan flat, do not photograph. Thermal stock is glossy. A phone flash produces a specular highlight that saturates the sensor exactly where the paper is flattest, and low-contrast text under a blown highlight is unrecoverable. A flatbed with its lid closed gives even, diffuse light.
- Turn off every automatic correction. Scanner software defaults to auto-contrast, auto-crop and despeckle. Each one makes a normal document better and a faded one worse: auto-contrast clips the faint end, despeckle removes marks it cannot distinguish from noise. Capture a flat, uncorrected grayscale at high resolution and do the processing yourself.
- Use a local threshold, not a global one. Thermal fading is a gradient — the parts that were handled, folded or exposed go first, so one sheet can hold readable text at the top and nothing at the bottom. A single global cut point sacrifices one end to save the other. An adaptive threshold over a small window keeps both.
- Try transmitted light. Backlighting sometimes helps because the imaged coating and the blank coating transmit differently even when they reflect almost identically. It is cheap to try and it occasionally recovers a line that reflected light does not.
- Then treat the result as an ordinary OCR input. Everything in the general OCR pipeline applies from this point; nothing about the medium is special once you have the best available image.
Extract partially, on purpose
The design decision that makes this workable is accepting up front that the output will be incomplete, and building a schema that can say so precisely. There is a pattern to what survives, and it is not random: the top of the strip carries the merchant name in large, dense type and is the most robust; the line items are small and go early; and the total is near the bottom, which is the end that gets handled, folded into a pocket and rubbed.
So the field you most need is the field most likely to be gone. Rather than treating that as failure, decide which fields are load-bearing and where each can be sourced from:
{
"merchant_name": { "value": "PARKSIDE CAFE", "source": "image" },
"date": { "value": "2026-03-14", "source": "image" },
"total": { "value": null, "source": null,
"reason": "illegible_faded" },
"subtotal": { "value": null, "source": null,
"reason": "illegible_faded" },
"line_items": [],
"coverage": 0.35
}
A record like that is useful. It says the receipt is genuine, names the merchant and the date, and states plainly that the amount must come from somewhere else — which, for anything paid by card, it can: the statement line carries the amount and date authoritatively and the receipt was only ever needed for the merchant and the itemisation. Reframing the paper as corroboration rather than as the source of the number turns most faded receipts from a blocker into a partial match.
The two anti-patterns to design against are a schema that cannot represent absence, so a missing total becomes 0.00, and a confidence score that only exists at the document level, so a receipt with a perfect merchant name and no amounts scores in the middle and tells nobody anything. Per-field values with per-field reasons are the fix, and the queueing and sampling machinery around them is covered in per-field extraction confidence.
Stop it happening to the next one
The permanent fix is upstream and it is unglamorous: capture the image on the day, and stop treating the paper as the record. A photograph taken at the table, stored as the primary artefact, removes the entire problem class for every future receipt. Tax authorities in most jurisdictions accept electronic records provided the system meets their requirements for legibility, retention and reproduction — the IRS publishes those requirements for electronic storage systems, and they are worth reading once rather than assuming.
Where paper must be kept, the storage rules follow directly from the chemistry: no heat, no direct sunlight, no PVC sleeves or plastic wallets, no adhesive tape across the printed face, and no proximity to solvents. Interleaving with plain paper in a manila envelope is better than any transparent pocket. And keep receipts flat — the fold is where the coating cracks and where the fade always starts.
Top comments (0)