OCRmyPDF

ocrmypdfMPL-2.0活跃维护

给扫描版 PDF 加上 OCR 文字层,让原本只能看的图片型 PDF 变成可搜索、可复制文本的文件。

OCRmyPDF adds an OCR text layer to scanned PDF files, allowing them to be searched

v17.14.0发布于 2026-11-08 21:00 UTC35,284star +24 / 7 天2,450fork同步于 2026-11-10 11:20 UTC

怎么上手

由 README 提炼,执行前请确认
apt install ocrmypdf
ocrmypdf --output-type pdfa input.pdf output.pdf
硬件要求按 README 说明

README 未说明显存或 GPU 要求;纯 Python 实现,可运行在 Linux、macOS、Windows、FreeBSD,需额外安装 Ghostscript 和 Tesseract OCR。

下载:源码 zip·GitHub Releases(安装包)本站不镜像安装包

项目说明

由 README 自动翻译提炼

给扫描版 PDF 加 OCR 文字层的命令行工具,让 PDF 可搜索可复制

给扫描版 PDF 加上 OCR 文字层,让原本只能看的图片型 PDF 变成可搜索、可复制文本的文件。

核心能力

  • 把 OCR 文字层精确放在图像下方,方便复制粘贴
  • 默认输出 PDF/A 归档格式并校验输入输出文件
  • 尽可能以无损方式插入 OCR 信息,不破坏原有内容
  • 优化 PDF 图像,常能生成比输入更小的文件
  • 按 CPU 核心数并行处理,可应对数千页文件

容易踩的坑

需单独安装 Ghostscript 和 Tesseract OCR 外部程序;非英语识别要另装 Tesseract 语言包并用 -l 指定;Tesseract 需 4.1.1 及以上版本。

内容由模型根据 README 生成,可能不完整或不准确,以官方文档为准。看原文 README

最近发版

5 个版本v17.14.0
  1. v17.14.0最新正式版2026-11-08 · 2026-11-08 21:00 UTC

    New features

    • New optional OCR engine, RapidOCR, which runs PaddleOCR's PP-OCR models on ONNX Runtime. Install it with uv tool install 'ocrmypdf[rapidocr]' (or uv pip install / pip install with the same extra) and select it with --ocr-engine rapidocr. It often reads numbers and table cells more accurately than Tesseract, at a higher CPU and memory cost. It supports --rotate-pages and --deskew without Tesseract, and the new option --rapidocr-max-side-len (API: rapidocr_max_side_len=) controls how far large pages are downscaled. See the cookbook for languages and limitations.
    • With RapidOCR, --rotate-pages uses PaddlePaddle's PP-LCNet_x1_0_doc_ori page orientation model (6.8 MB, Apache-2.0), downloaded on first use and checked against its checksum, together with the shape of the detected text lines. A page is turned only when both agree.
    • python -m ocrmypdf.builtin_plugins.rapidocr_ocr download [LANGUAGE...] downloads RapidOCR's page orientation model and any additional language models in advance, for offline use or container images.
    • The Docker images do not include RapidOCR, to keep them small. .docker/Dockerfile.rapidocr builds an image with RapidOCR, its page orientation model and any additional languages on top of the Ubuntu image.

    Fixes

    • Selecting an OCR engine other than Tesseract, including --ocr-engine none, no longer requires Tesseract to be installed.
    • Fixed --redo-ocr and --mode strip removing visible text from a text object that also contains invisible text, such as when the text rendering mode changes to invisible partway through it. Only the invisible text is now removed, and font and spacing settings made where it is removed are kept for the text that follows. {issue}1769
    • Fixed the fpdf2 renderer writing the text of a line that rises to the right too large, by up to the height of its rise, which also made the text of neighbouring lines overlap. A sloped line's box spans its rise as well as its text; the text size is now measured at the end of the line where the baseline is highest, as it already was for lines that fall to the right.
  2. v17.13.02026-09-28 · 2026-09-28 18:55 UTC
    查看更新说明

    Changes

    • PDF/A made without Ghostscript ("speculative" conversion) is now validated with pikepdf's PDF/A support (pikepdf.pdfa) instead of veraPDF, and the final output is validated again after the metadata and optimization steps. veraPDF is no longer used, so the Ghostscript-free path is available whether or not veraPDF is installed, including in the Docker image. Files the validator does not approve go to Ghostscript as before; run with -v1 to see why.
    • Speculative conversion now supports PDF/A-1b, and repairs common problems that previously always sent a file to Ghostscript: it replaces other output intents with sRGB, removes image interpolation flags, sets the Print flag on annotations, adds the /CIDSet PDF/A-1 requires, and removes XMP properties and hidden annotations that PDF/A does not permit.
    • New option --pdfa-backend {auto,ghostscript,internal} (API: pdfa_backend=). auto, the default, tries OCRmyPDF's own conversion and then Ghostscript. internal never uses Ghostscript, so JPEGs pass through unchanged; if the result is not approved, the pdfa output types fail with exit code 10 and --output-type auto outputs a regular PDF. ghostscript always uses Ghostscript. Options that only Ghostscript implements (--pdfa-image-compression, --ghostscript-jpeg-quality, --ghostscript-jpeg-maxdpi, and --color-conversion-strategy CMYK, Gray or UseDeviceIndependentColor) now select Ghostscript under auto and are an error with internal.
    • OCRmyPDF now requires pikepdf[pdfa] 10.15 or later. The pdfa extra brings in jsonschema, referencing and fonttools, all packaged by Debian and Red Hat.
    • --force-ocr now keeps hyperlinks, moving link annotations onto the rasterized page; so do --deskew and --clean-final. The new mode --mode force-ocr-no-links keeps the old behaviour. {issue}605
    • When Ghostscript substitutes fonts that are not embedded, it now always uses its own fonts (-dNONATIVEFONTMAP), so output is the same on every platform; on macOS, native font lookup could embed tens of megabytes of system fonts. OCRmyPDF warns when fonts other than the standard 14 are substituted, or when a substitute loses bold or italic styling. {issue}1369
    • A creation date without a time zone is now taken to be local time, and the output's dates get that zone, with a warning. Set TZ to choose another zone.
    • In the default mode, a page that already has text now stops OCRmyPDF straight after the initial scan, instead of after OCRing the pages before it. The error names the page. {issue}613
    • The check of the output file is much faster: each stream is checked in the cheapest way for its compression instead of being fully decoded, and a progress bar is shown. JPEG 2000 and CCITT images are now checked too, but JPEGs that are corrupt without being truncated are no longer detected. {issue}1570
    • OCRmyPDF now ships a PyInstaller hook, so apps that use it can be bundled without extra options. Tesseract and Ghostscript must still be installed. {issue}1024
    • New PageInfo.has_visible_text, which excludes invisible text such as an OCR layer. has_text is unchanged.

    Fixes

    • --force-ocr on a scan that already had an invisible OCR layer rasterized it at no less than 400 dpi, as if the text were visible, which could multiply the file size. {issue}961
    • Process workers (use_threads=False on Windows and macOS) failed on every page with 'OcrOptions' object has no attribute 'tesseract'. {issue}1757
    • ocrmypdf.ocr() rejected thresholding method names such as tesseract_thresholding='adaptive-otsu'. {issue}1460
    • --rotate-pages --tesseract-timeout 0 detected page orientation but did not rotate the pages. The cookbook now recommends this combination for rotating or deskewing without OCR. {issue}778
    • With --output-type auto and --force-ocr, output was labelled PDF/A without bein
  3. v17.12.12026-09-16 · 2026-09-16 23:20 UTC
    查看更新说明

    Fixes

    • ocrmypdf --version and ocrmypdf --help printed to standard error instead of standard output, so version=$(ocrmypdf --version) came back empty and ocrmypdf --help | less showed nothing. OCRmyPDF redirects file descriptor 1 to standard error early in startup, before it parses the command line, so that a stray write from a plugin or a library cannot corrupt a PDF being written to standard output; argparse's own output was caught by that redirection too and is now routed back to the real standard output. Error messages continue to go to standard error. Broken since v17.8.0.
  4. v17.12.02026-09-16 · 2026-09-16 20:43 UTC
    查看更新说明

    Changes

    • OCRmyPDF now requires pikepdf 10.2 or later, up from pikepdf 10. This is the first release that provides pikepdf.NamePath, the Object.as_int() family of type-safe accessors, and a thread-local explicit_conversion(). OCRmyPDF uses all three to read optional values out of PDFs it did not write.
    • HEIF/HEIC input support is now an opt-in extra, ocrmypdf[heic], instead of a default dependency. The pi-heif package we previously depended on is discontinued; its successor pillow-heif bundles libheif, libde265 and x265 in its wheels, making the wheel as a whole GPLv2-licensed, so we do not install it by default. Install ocrmypdf[heic] if you feed HEIC images to OCRmyPDF. The Docker image and snap do not include it. {issue}1746
    • A Tagged PDF that is refused because it appears to contain real text now exits with code 6 (already_done_ocr) instead of code 2 (input_file), matching the exit code for a PDF with prior OCR. Scripts that check for exit code 2 on tagged PDFs need updating. Thanks @BetterAndBetterII. {issue}1551
    • The snap package is now built and published from our CI rather than Launchpad, so the stable channel tracks releases again instead of being frozen at v16.4.2. It is based on core26 and includes a JBIG2 encoder.

    Fixes

    • Text copied or searched in a --output-type pdfa file came out as garbage (a stable substitution of unrelated characters, or nothing at all) when the PDF/A conversion ran through Ghostscript 9.56 through 10.04.x, which includes the Ghostscript in Ubuntu 24.04. fpdf2 writes each font's ToUnicode CMap as a single bfchar block, but the CMap specification allows at most 100 entries per block, and those Ghostscript releases discard the whole map when a block is larger. Any page with more than 100 distinct glyphs was affected, which is nearly every page of prose. CFF CID-keyed fonts such as Noto Sans CJK have the same problem in their Encoding CMap, where those Ghostscript releases then also draw the wrong glyphs. OCRmyPDF now splits every CMap block to 100 entries as fpdf2 writes it, for every fpdf2 release. fpdf2 2.8.9 will split the ToUnicode blocks itself but not the Encoding blocks, so the fix stays in place. Thanks @olafure for the analysis ({issue}1747, fpdf2 issue py-pdf/fpdf2#1952).
    • Words containing fi, ff, fl and similar pairs extracted with the letters missing (con dentiality, e ects) from --output-type pdfa files when the PDF/A conversion ran through Ghostscript 10.05.0 through 10.06.x. Those Ghostscript releases drop ToUnicode entries that expand to more than one character (Ghostscript bug 709030, fixed in 10.07.0), and the fpdf2 renderer's HarfBuzz shaping had been forming optional Latin ligatures whose entries do exactly that. Invisible text in scripts that do not need shaping is now encoded one glyph per character, so no such entries exist to lose. Complex scripts still get shaped, and OCRmyPDF now warns when an affected Ghostscript is in use, since their conjunct mappings can still be dropped. Thanks @kmn5 ({issue}1744).
    • A malformed PDF that stores something other than a dictionary at a structural key -- /Resources, /Resources /XObject, /Root /AcroForm, /Root /MarkInfo, /Root /Names, /Root /PieceInfo, an annotation's /A, or an image's /SMask -- is now tolerated everywhere rather than in the handful of places that had been hardened individually. Such a file is read as though the key were absent, which is what the well-guarded paths already did.
    • An image XObject with no /Subtype no longer raises out of the optimizer.
    • PdfInfo no longer aborts on a /MarkInfo << /Marked 1 >>, where a producer wrote a flag as an integer instead of a Boolean. Thanks @linhongyu510 ({issue}1742).
    • A page /UserUnit written as a PDF Real is now read exactly rather than via binary floating point, so the digits the file wrote are the dig
  5. v17.11.02026-08-28 · 2026-08-28 22:15 UTC
    查看更新说明

    Enhancements

    • New --max-ocr-image-mpixels downsamples the image sent to OCR when a page exceeds the given size, which bounds the largest consumer of memory. The visible page is never downsampled, so output appearance is unaffected in every mode; what it trades is OCR accuracy on very high resolution scans. A 34 megapixel page that peaks at 492 MB peaks at 325 MB under --max-ocr-image-mpixels 8, and recognizes the same text. See the "Memory" section of the performance documentation for how to size a memory limit.
    • watcher.py (the watcher extra) gained a configurable output layout and conflict policy. These are watcher-only changes; they do not affect the ocrmypdf library API.
      • New OCR_OUTPUT_STRUCTURE setting (--output-structure): FLAT (default, all outputs directly in the destination directory), YEAR_MONTH ({destination}/{year}/{month}/{filename}, same layout as the old OCR_OUTPUT_DIRECTORY_YEAR_MONTH=1), or HIERARCHY, which mirrors the input directory tree under the destination, e.g. input/a/b/c.pdf → output/a/b/c.pdf.
      • New OCR_ON_CONFLICT setting (--on-conflict) controls what happens when the intended destination file already exists: SUFFIX (default) writes name (1).pdf, name (2).pdf, ... in the OS style; SKIP logs and leaves the file unprocessed; OVERWRITE is the old behavior. Behavior change: the default is now SUFFIX, so existing output files are no longer silently overwritten.
      • Both settings now apply equally to OCR_OUTPUT_DIRECTORY and to the archive directory used by OCR_ON_SUCCESS_ARCHIVE; previously the archive directory was always flat and silently overwrote on a name collision.
      • Output and archive filenames and directory components are sanitized for filesystems more restrictive than the input side (e.g. an SMB share): characters illegal on Windows/SMB (<>:"/\|?* and control characters) are replaced with _, trailing dots/spaces are stripped, and reserved DOS device names (CON, PRN, AUX, NUL, COM1-9, LPT1-9) are prefixed with _.
      • OCR_OUTPUT_DIRECTORY_YEAR_MONTH is now deprecated in favor of OCR_OUTPUT_STRUCTURE=YEAR_MONTH. It is still honored and logs a deprecation warning; if both are set, OCR_OUTPUT_STRUCTURE wins.
      • See the "Watched folders with watcher.py" section of the batch processing documentation for the full description, including a note for SMB users about client-side directory/file-info caching delays.

    Performance

    • The image sent to OCR is no longer decoded and re-encoded when nothing needs to change it. On a page with no pre-existing text to mask and no filtering plugin -- the ordinary case for a scanned document -- the rasterized page already is the OCR image, so it is linked rather than rewritten. Producing it was costing 3.3 seconds and a full-size buffer on a 34 megapixel page, out of about 15 seconds for the whole file. Building the mask is now deferred until a text area actually needs blanking, since that step is what forced the decode. The minimum Pillow version is raised to 12, because deciding whether anything decoded the image reads an attribute whose shape settled in Pillow 11 (pi-heif already required Pillow 11.1, so the effective floor barely moves).
    • Reduced peak memory on files with large images by about a third at default settings. On a 34 megapixel page the process tree peaked at 752 MB and now peaks at 492 MB. Two changes account for it: rasterizing a page no longer allocates a third full-page buffer to correct PDFium's rounding of the rendered size by a pixel or two, and freed heap memory is now returned to the operating system before the OCR engine runs, instead of counting against our resident set for as long as the engine is working. Rasterization is also faster, since correcting

用户点评

登录用户的真实使用记录,可按版本和硬件筛选
共 0 条

    还没有人点评。第一个说出真实体验的人最有价值。

    README 原文

    未翻译

    Build Status PyPI version Homebrew version ReadTheDocs Python versions

    OCRmyPDF adds an OCR text layer to scanned PDF files, allowing them to be searched or copy-pasted.

    ocrmypdf                      # it's a scriptable command line program
       -l eng+fra                 # it supports multiple languages
       --rotate-pages             # it can fix pages that are misrotated
       --deskew                   # it can deskew crooked PDFs!
       --title "My PDF"           # it can change output metadata
       --jobs 4                   # it uses multiple cores by default
       --output-type pdfa         # it produces PDF/A by default
       input_scanned.pdf          # takes PDF input (or images)
       output_searchable.pdf      # produces validated PDF output
    

    See the release notes for details on the latest changes.

    Main features

    • Generates a searchable PDF/A file from a regular PDF
    • Places OCR text accurately below the image to ease copy / paste
    • Keeps the exact resolution of the original embedded images
    • When possible, inserts OCR information as a "lossless" operation without disrupting any other content
    • Optimizes PDF images, often producing files smaller than the input file
    • If requested, deskews and/or cleans the image before performing OCR
    • Validates input and output files
    • Distributes work across all available CPU cores
    • Uses Tesseract OCR engine to recognize more than 100 languages
    • Keeps your private data private.
    • Scales properly to handle files with thousands of pages.
    • Battle-tested on millions of PDFs.

    For details: please consult the documentation.

    Motivation

    I searched the web for a free command line tool to OCR PDF files: I found many, but none of them were really satisfying:

    • Either they produced PDF files with misplaced text under the image (making copy/paste impossible)
    • Or they did not handle accents and multilingual characters
    • Or they changed the resolution of the embedded images
    • Or they generated ridiculously large PDF files
    • Or they crashed when trying to OCR
    • Or they did not produce valid PDF files
    • On top of that none of them produced PDF/A files (format dedicated for long time storage)

    ...so I decided to develop my own tool.

    Installation

    Linux, Windows, macOS and FreeBSD are supported. Docker images are also available, for both x64 and ARM.

    Operating systemInstall command
    Debian, Ubuntuapt install ocrmypdf
    Windows Subsystem for Linuxapt install ocrmypdf
    Fedoradnf install ocrmypdf
    macOS (Homebrew)brew install ocrmypdf
    macOS (MacPorts)port install ocrmypdf
    macOS (nix)nix-env -i ocrmypdf
    LinuxBrewbrew install ocrmypdf
    FreeBSDpkg install py-ocrmypdf
    OpenBSDpkg_add ocrmypdf
    Ubuntu Snapsnap install ocrmypdf

    For everyone else, see our documentation for installation steps.

    Languages

    OCRmyPDF uses Tesseract for OCR, and relies on its language packs. For Linux users, you can often find packages that provide language packs:

    
    # Debian/Ubuntu users
    apt-cache search tesseract-ocr # Display a list of all Tesseract language packs
    apt-get install tesseract-ocr-chi-sim  # Example: Install Chinese Simplified language pack
    
    
    # Arch Linux users
    pacman -S tesseract-data-eng tesseract-data-deu # Example: Install the English and German language packs
    
    # OpenBSD users
    pkg_info -aQ tesseract  # Display a list of all Tesseract language packs
    pkg_add tesseract-cym  # Example: Install the Welsh language pack
    
    # brew macOS users
    brew install tesseract-lang
    
    # Fedora users
    dnf search tesseract-langpack # Display a list of all Tesseract language packs 
    dnf install tesseract-langpack-ita # Example: Install the Italian language pack
    
    
    

    You can then pass the -l LANG argument to OCRmyPDF to give a hint as to what languages it should search for. Multiple languages can be requested.

    OCRmyPDF supports Tesseract 4.1.1+. It will automatically use whichever version it finds first on the PATH environment variable. On Windows, if PATH does not provide a Tesseract binary, we use the highest version number that is installed according to the Windows Registry.

    Documentation and support

    Once OCRmyPDF is installed, the built-in help which explains the command syntax and options can be accessed via:

    ocrmypdf --help
    

    Our documentation is served on Read the Docs.

    Please report issues on our GitHub issues page, and follow the issue template for quick response.

    Feature demo

    # Add an OCR layer and require PDF/A
    ocrmypdf --output-type pdfa input.pdf output.pdf
    
    # Convert an image to single page PDF
    ocrmypdf input.jpg output.pdf
    
    # Add OCR to a file in place (only modifies file on success)
    ocrmypdf myfile.pdf myfile.pdf
    
    # OCR with non-English languages (look up your language's ISO 639-3 code)
    ocrmypdf -l fra LeParisien.pdf LeParisien.pdf
    
    # OCR multilingual documents
    ocrmypdf -l eng+fra Bilingual-English-French.pdf Bilingual-English-French.pdf
    
    # Deskew (straighten crooked pages)
    ocrmypdf --deskew input.pdf output.pdf
    

    For more features, see the documentation.

    Requirements

    In addition to the required Python version, OCRmyPDF requires external program installations of Ghostscript and Tesseract OCR. OCRmyPDF is pure Python, and runs on pretty much everything: Linux, macOS, Windows and FreeBSD.

    Plugins

    OCRmyPDF provides a plugin interface allowing its capabilities to be extended or replaced. Here are some plugins we are aware of:

    • OCRmyPDF-AppleOCR: replaces the standard Tesseract OCR engine with Apple Vision Framework. Requires macOS.
    • OCRmyPDF-EasyOCR: replaces the standard Tesseract OCR engine with EasyOCR, a newer OCR engine based on PyTorch. GPU strongly recommended.
    • OCRmyPDF-PaddleOCR: replaces the standard Tesseract OCR engine with PaddleOCR, a powerful GPU accelerated OCR engine.

    paperless-ngx provides integration of OCRmyPDF into a searchable document management system.

    Press & Media

    Business enquiries

    OCRmyPDF would not be the software that it is today without companies and users choosing to provide support for feature development and consulting enquiries. We are happy to discuss all enquiries, whether for extending the existing feature set, or integrating OCRmyPDF into a larger system.

    License

    The OCRmyPDF software is licensed under the Mozilla Public License 2.0 (MPL-2.0). This license permits integration of OCRmyPDF with other code, included commercial and closed source, but asks you to publish source-level modifications you make to OCRmyPDF.

    Some components of OCRmyPDF have other licenses, as indicated by standard SPDX license identifiers or the DEP5 copyright and licensing information file. Generally speaking, non-core code is licensed under MIT, and the documentation and test files are licensed under Creative Commons ShareAlike 4.0 (CC-BY-SA 4.0).

    Disclaimer

    The software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.