diff --git a/ocrmypdf/__main__.py b/ocrmypdf/__main__.py index e2cc790e..3791a019 100755 --- a/ocrmypdf/__main__.py +++ b/ocrmypdf/__main__.py @@ -222,14 +222,15 @@ advanced.add_argument( "3 - default.") ) advanced.add_argument( - '--pdf-renderer', choices=['auto', 'tesseract', 'hocr', 'tesstop'], default='auto', + '--pdf-renderer', choices=['auto', 'tesseract', 'hocr', 'tess4'], default='auto', help="choose OCR PDF renderer - the default option is to let OCRmyPDF " "choose. The 'tesseract' PDF renderer is more accurate and does a " "better job and document structure such as recognizing columns. It " "also does a better job on non-Latin languages. However, it does " "not work as well when older versions of Tesseract or Ghostscript " "are installed, and some combinations of arguments to do not work " - "with --pdf-renderer tesseract.") + "with --pdf-renderer tesseract. The 'tess4' PDF renderer is similar " + "to 'tesseract', requires tesseract 4, and gives superior results.") advanced.add_argument( '--tesseract-timeout', default=180.0, type=float, metavar='SECONDS', help='give up on OCR after the timeout, but copy the preprocessed page ' diff --git a/ocrmypdf/pipeline.py b/ocrmypdf/pipeline.py index 70c6ed2e..d0f61fd2 100644 --- a/ocrmypdf/pipeline.py +++ b/ocrmypdf/pipeline.py @@ -970,7 +970,7 @@ def build_pipeline(options, work_folder, log, context): task_select_image_layer.graphviz( fillcolor='"#00cc66"', shape='diamond') task_select_image_layer.active_if( - options.pdf_renderer == 'hocr' or options.pdf_renderer == 'tesstop') + options.pdf_renderer == 'hocr' or options.pdf_renderer == 'tess4') task_render_hocr_page = main_pipeline.transform( task_func=render_hocr_page, @@ -999,7 +999,7 @@ def build_pipeline(options, work_folder, log, context): output=os.path.join(work_folder, r'\1.text.pdf'), extras=[log, context]) task_ocr_tesseract_textonly_pdf.graphviz(fillcolor='"#ff69b4"') - task_ocr_tesseract_textonly_pdf.active_if(options.pdf_renderer == 'tesstop') + task_ocr_tesseract_textonly_pdf.active_if(options.pdf_renderer == 'tess4') if tesseract.v4(): task_ocr_tesseract_textonly_pdf.jobs_limit(1) @@ -1012,7 +1012,7 @@ def build_pipeline(options, work_folder, log, context): output=os.path.join(work_folder, r'\1.rendered.pdf'), extras=[log, context]) task_combine_layers.graphviz(fillcolor='"#00cc66"') - task_combine_layers.active_if(options.pdf_renderer == 'hocr' or options.pdf_renderer == 'tesstop') + task_combine_layers.active_if(options.pdf_renderer == 'hocr' or options.pdf_renderer == 'tess4') # Tesseract OCR+PDF task_ocr_tesseract_and_render_pdf = main_pipeline.collate( diff --git a/tests/test_tess4.py b/tests/test_tess4.py new file mode 100644 index 00000000..9dfc1e98 --- /dev/null +++ b/tests/test_tess4.py @@ -0,0 +1,88 @@ +#!/usr/bin/env python3 +# © 2017 James R. Barlow: github.com/jbarlow83 + +from __future__ import print_function +from subprocess import Popen, PIPE, check_output, check_call, DEVNULL +import os +import shutil +from contextlib import suppress +import sys +import pytest +from ocrmypdf.pageinfo import pdf_get_all_pageinfo +import PyPDF2 as pypdf +from ocrmypdf.exceptions import ExitCode +from ocrmypdf import leptonica +from ocrmypdf.pdfa import file_claims_pdfa +from ocrmypdf.exec import tesseract +import platform + + +if sys.version_info.major < 3: + print("Requires Python 3.4+") + sys.exit(1) + +TESTS_ROOT = os.path.abspath(os.path.dirname(__file__)) +SPOOF_PATH = os.path.join(TESTS_ROOT, 'spoof') +PROJECT_ROOT = os.path.dirname(TESTS_ROOT) +TEST_RESOURCES = os.path.join(PROJECT_ROOT, 'tests', 'resources') +OCRMYPDF = [sys.executable, '-m', 'ocrmypdf'] + + +# Skip all tests in this file if not tesseract 4 +pytestmark = pytest.mark.skipif(not tesseract.v4(), + reason="tesseract 4.0 required") + + +def running_in_docker(): + # Docker creates a file named /.dockerinit + return os.path.exists('/.dockerinit') + + +def is_linux(): + return platform.system() == 'Linux' + + +def _infile(input_basename): + return os.path.join(TEST_RESOURCES, input_basename) + + +def check_ocrmypdf(input_basename, output, *args, env=None): + "Run ocrmypdf and confirmed that a valid file was created" + input_file = _infile(input_basename) + + p, out, err = run_ocrmypdf(input_basename, output, *args, env=env) + print(err) # ensure py.test collects the output, use -s to view + assert p.returncode == 0 + assert os.path.exists(output), "Output file not created" + assert os.stat(output).st_size > 100, "PDF too small or empty" + assert out == "", \ + "The following was written to stdout and should not have been: \n" + \ + "\n" + out + "\n" + return output + + +def run_ocrmypdf(input_basename, output, *args, env=None): + "Run ocrmypdf and let caller deal with results" + input_file = _infile(input_basename) + + if env is None: + env = os.environ + + p_args = OCRMYPDF + list(args) + [input_file, output] + p = Popen( + p_args, close_fds=True, stdout=PIPE, stderr=PIPE, + universal_newlines=True, env=env) + out, err = p.communicate() + print(err) + + return p, out, err + + +@pytest.mark.skipif(not tesseract.has_textonly_pdf(), + reason="requires textonly_pdf parameter") +def test_textonly_pdf(self, tmpdir): + output = str(tmpdir.join("linn_textonly.pdf")) + check_ocrmypdf('linn.pdf', output, '--pdf-renderer', 'tess4') + + +