OCR Service
UniPDF does not recognize text in images itself. The ocr package is an HTTP client:
it packs an image into a multipart form, posts it to a URL you configure, and returns
the response body unchanged. The recognition happens in whatever service sits at that
URL, so nothing on these pages works until you have one running.
That also means UniPDF never parses the result. ExtractText returns []byte straight
from the response, and decoding it is your job, whether the service sent back JSON,
plain text or hOCR.
What you need
A service that accepts a file upload as multipart form data and returns recognized
text. The examples were written against unidoc/ocrserver,
which wraps Tesseract and answers on http://localhost:8080/file:
git clone https://github.com/unidoc/ocrserver.git
cd ocrserver
docker-compose upThe OCR service needs no UniDoc credentials of its own, and the ocr package makes no
license calls. The metered key the examples load in init matters only for the reader
and creator work around it, such as pulling images out of a PDF or writing a new one.
Configuring the client
Everything goes through ocr.OCROptions. Only Url has no default:
| Field | Default | Notes |
|---|---|---|
Url | none | Required. ExtractText returns an error if it is empty. |
Method | POST | |
FileFieldName | file | The multipart field the image is attached to. |
Headers | empty | Applied after the multipart Content-Type, so a Content-Type here would override it. |
FormFields | empty | Extra text fields in the same form. This is how you ask for hOCR. |
TimeoutSeconds | 30 | Ignored when Client is set. |
MaxRetries | 0 | Retries fire on any non-2xx response, not just transport errors. |
Client | nil | Supply your own *http.Client for proxies, TLS config or connection pooling. |
RequestModifier | nil | Called just before the request is sent, for signing or auth headers. |
The field is Url, not URL.
Two entry points
NewHTTPOCRService returns the low-level *HTTPOCRService. NewOCRHTTPClient wraps
the same service in a *Client that adds convenience methods. Both answer
ExtractText(ctx, reader, filename), so single-image code looks identical either way.
| Call | Only on *Client | What it adds |
|---|---|---|
ExtractText | no | Reader plus filename. |
ExtractTextFromFile | yes | Opens and closes the file for you. |
ExtractTextFromImage | yes | Takes a *model.Image and posts image.Data as image.jpg. |
BatchProcess | yes | Concurrent, over []*model.Image. |
BatchProcessFiles | yes | Concurrent, over file paths. |
CallEndpoint | no | Plain request to the configured URL with no multipart body, for a health check or a status endpoint. |
ExtractTextFromImage posts model.Image.Data as-is under the name image.jpg.
model.Image holds decoded samples rather than an encoded file, so most services will
reject it. The reconstruct example works around this by calling ToGoImage and
encoding to JPEG itself, which is the pattern to copy.
Output format
Plain text is the default, because it is whatever the service returns by default.
Asking for hOCR is a FormFields entry, and the key depends on the service.
ocrserver uses format:
opts.FormFields = map[string]string{"format": "hocr"}hOCR is HTML with the geometry encoded in title attributes: bounding boxes, baseline,
x_size for text height, and x_wconf for per-word confidence. Reach for it when you
need to know where a word sits on the page. Stay with plain text when you only need the
words.
Where to look
| Guide | Covers |
|---|---|
| Extract text from a single image | The minimal request, and the options that shape it. |
| Get hOCR output | Asking for hOCR, and reading the geometry back out. |
| Batch processing of images | Concurrency, and the parallel error slice. |
| Reconstruct PDF from hOCR | Images out of a scanned PDF, hOCR in, positioned text out. |