OCR / Text Extraction
Text out, boxes drawn, and the prompt matters more than you'd expect
- unlimited_ocr
- image
- config
- extracted_text
- annotated_image
- debug_text
Here's the payoff node. Wire it the model handle from Load Unlimited OCR Model, feed it any image, and you get three things out: clean extracted text, the image with colored bounding boxes drawn around every detected element, and the model's raw annotated output. All of it local, no API in sight.
This is the one you actually reach for. Florence-2 has an OCR mode, but it's a small general-purpose model built for quick captioning; Unlimited-OCR's whole job is reading long, dense, structured pages in a single pass. Receipts, scanned contracts, screenshots of tables, game dialogue, PDF pages that refuse to give up their text. The vision-language corner of ComfyUI mostly gets talked about for captioning LoRA sets, but OCR is where a VLM's ability to read text in context genuinely shines - no multi-subject attribution fights to worry about here.
The inputs
- unlimited_ocr - the model handle from the Loader.
- image - any ComfyUI image tensor.
- prompt (default
"document parsing.") - this matters more than you'd think. The prompt steers the OCR mode; the placeholder suggests"extract text."as the alternative. It's not a description of the image, it's an instruction for how to parse it. - config (optional) - the output of Configure Inference. Skip it and sensible defaults kick in.
What comes out
- extracted_text - the cleaned text with all box annotations stripped out. This is the string you actually want, and the one to send to a Save Text or show node.
- annotated_image - the input with bounding boxes drawn, color-coded by element type: titles red, headers green, footers blue, body text yellow, tables cyan, images magenta. Great for eyeballing whether the model saw the layout the way you do.
- debug_text - the raw model output including the
<|det|>label [x1,y1,x2,y2]<|/det|>tags. Reach for it when the cleaned text looks wrong and you want to see what the model actually said.
How it works
Under the hood the node converts your image tensor to PIL, saves it to a temp file (the model reads from a path, not from memory), and runs inference with your prompt and config. The model emits its layout annotations inline; the node regex-parses those tags, scales the normalized 0–999 coordinates to your actual image dimensions, draws the boxes, then strips the tags to produce clean text. Temp files are cleaned up afterward, so you won't find OCR litter in your output folder.
Troubleshooting
- Empty prompt - hard error ("prompt cannot be empty"). It trims whitespace, so just don't leave it blank.
- Poor extraction - feed a higher-resolution image, bump
image_sizein the config, or raisemax_lengthfor very long documents. - Slow first run - the model is downloading. After that, expect a one-shot decode rather than per-line speed; it's built for accuracy on long pages, not for racing PaddleOCR.
Wire extracted_text into a text preview, save annotated_image somewhere, and you've got a fully local OCR pipeline. The whole pack exists to make that one connection work.
Inputs (4)
| Name | Type | Default | Description |
|---|---|---|---|
| unlimited_ocr | unlimited_ocr_model | — | |
| image | IMAGE | — | |
| prompt | STRING | document parsing. | — |
| configopt | unlimited_ocr_config | — |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| extracted_text | text | — |
| annotated_image | IMAGE | — |
| debug_text | text | — |