I added offline OCR and text extraction to pdfcpu A fork of the Go PDF library pdfcpu, named pdfcpu2, adds offline OCR and PDFBox-compatible text extraction while keeping the original PDF processing commands, shipping as a single static binary with no Python, cgo, or external services. The fork embeds the PP-OCRv6_tiny detection and recognition models (about 6 MB) and runs inference on a pure Go engine using fp32 scalar math and goroutine-based parallelism, with text extraction tuned through differential testing against Apache PDFBox on a corpus of more than 1,200 real-world Chinese PDFs. PaddlePaddle's published benchmark reports PP-OCRv6_tiny at 80.6 text detection and 73.5 text recognition, versus 46.8 and 71.4 for Gemini-3.1-Pro and 45.6 and 64.2 for GPT-5.5, and the fork's author says the features fill a need he had in his own work despite his respect for pdfcpu maintainer Horst Rutter's commitment to the PDF standard. pdfcpu2 is a fork of pdfcpu that adds offline OCR and text extraction while retaining the existing PDF processing commands. It builds as a single static binary, with no Python, cgo, or external services required. pdfcpu2 ocr scan.pdf scan ocr.pdf && pdfcpu2 extract -m text scan ocr.pdf - This adds a searchable text layer to a scanned PDF and extracts the resulting text. The same pipeline can be used for RAG ingestion, agent tools, and batch document processing. | pdfcpu2 extract -m text : extract text from a PDF | pdfcpu2 ocr : add an invisible, selectable text layer to scans | |---|---| The project wiki https://github.com/huzpsb/pdfcpu2/wiki contains about 60 pages of documentation, including CLI usage, Go API examples, and getting-started guides. Horst Rutter, the maintainer of pdfcpu, is a member of the PDF Association. I admire his commitment to the PDF standard. But I genuinely need text extraction, OCR, and related features in my own work. Respect for his work does not remove that need, so I added them here and use them. - Single binary. The PP-OCRv6 detection and recognition models about 6 MB are embedded in the executable. OCR runs offline without API keys, tokens, rate limits, or data leaving the local machine. Windows, Linux, and macOS are supported on amd64 and arm64. - Pure Go OCR inference. The models run on a pure Go engine using fp32 scalar math and goroutine-based parallelism. No cgo, ONNX Runtime, or Python is required. - OCR benchmarks. PaddlePaddle's published benchmark reports the following results for PP-OCRv6 and several general-purpose VLMs:Model Text detection Text recognition PP-OCRv6 medium 86.2 83.2 PP-OCRv6 small 84.1 81.3 PP-OCRv6 tiny embedded 80.6 73.5 Gemini-3.1-Pro 46.8 71.4 GPT-5.5 45.6 64.2 Qwen3-VL-235B 38.3 74.9 Source: PP-OCRv6 model card https://www.modelscope.cn/models/PaddlePaddle/PP-OCRv6 small rec onnx . The specialized models also have no per-page API cost. - PDFBox-compatible text extraction. extract -m text follows Apache PDFBox's default extractor. Behavior has been tuned through differential testing against PDFBox on a corpus of more than 1,200 real-world Chinese PDFs from different periods and generators. - CJK support. Text extraction handles ToUnicode CMaps including Type42 and array-form bfrange , embedded TrueType cmaps, legacy GBK/Big5, Adobe-GB1/CNS1 CID fallbacks, and a Latin-1 last resort. The OCR models are trained for Chinese and English. - Repeatable OCR. Processed images are marked, so running ocr again only processes new content. Text is added as an invisible layer mapped through each image's page transform, keeping selection aligned with the visible glyphs. - CLI and API integration. Supports stdin/stdout streaming - , page selection, JSON output, and context.Context cancellation in the Go API. | Feature | Command | Status | |---|---|---| | Plain-text extraction PDFBox-compatible | pdfcpu2 extract -m text | Available | | Invisible OCR text layer for scanned PDFs | pdfcpu2 ocr | Available | | Page rendering / rasterization | pdfcpu2 render | Planned | Text extraction pdfcpu2 extract -m text in.pdf out.txt whole document pdfcpu2 extract -m text -p 1-3 in.pdf - pages 1-3 to stdout OCR: make scans searchable and extractable pdfcpu2 ocr scan.pdf scan ocr.pdf all pages pdfcpu2 ocr scan.pdf scan ocr.pdf -pages 1-10 selected pages As Go code: conf := model.NewDefaultConfiguration ctx := context.Background n, err := api.OCRFile ctx, "scan.pdf", "scan ocr.pdf", nil, conf // images processed err = api.ExtractTextFile ctx, "scan ocr.pdf", "out.txt", nil, nil, conf // Or extract structured text with line coordinates: texts, err := api.ExtractText ctx, rs, string{"1-3"}, nil, conf // pdfcpu.PageText The existing command set remains available, including validation, optimization, merge/split/trim, pages and boxes, stamps and watermarks, forms, encryption, permissions, signatures, attachments, PDF creation, n-up, booklets, and posters. pdfcpu2 validate in.pdf pdfcpu2 merge out.pdf a.pdf b.pdf pdfcpu2 encrypt --opw owner --upw user in.pdf out.pdf AES-256 pdfcpu2 stamp add "CONFIDENTIAL" "pos:tr, op:.6" in.pdf out.pdf go install github.com/huzpsb/pdfcpu2/cmd/pdfcpu2@latest Or from a checkout: go mod vendor && go build ./cmd/pdfcpu2 As a library: go get github.com/huzpsb/pdfcpu2 pdfcpu2 is an independently maintained hard fork of pdfcpu, licensed under Apache 2.0. It is not guaranteed to track upstream releases. Issues and reasonable feature requests are welcome. Existing behavior and API conventions remain compatible where practical. New code follows the existing package layering: model → pkg/pdfcpu → pkg/api → pkg/cli . Upstream project: pdfcpu https://github.com/pdfcpu/pdfcpu . Apache License 2.0, same as upstream see LICENSE.txt . The embedded Adobe CID-to-Unicode tables are derived from Adobe's UCS2 CMap resources Adobe BSD-style license; copyright notice retained in the generated file's header .