Compare commits

...
13 Commits
Author SHA1 Message Date
James R. Barlow c69ee63d82 Travis, true is a program, not a keyword 2017-05-15 15:12:14 -07:00
James R. Barlow 744fa104d7 v5.0.1 release notes (anticipating) 2017-05-14 23:59:09 -07:00
James R. Barlow e24ff0fd64 Travis: don’t update the homebrew version because we pushed to testpypi 2017-05-14 23:55:40 -07:00
James R. Barlow 5de107d44c tesseract_cache: update explanatory notes 2017-05-14 23:54:09 -07:00
James R. Barlow 131a5b741d tesseract.py: update canned HOCR template to tess 3.05 output
Seems better to not claim the existence of several entities that don’t
exist as the older one does
2017-05-14 23:40:09 -07:00
James R. Barlow 65b89687a9 ghostscript: fix missing “import sys”, only applicable for an exception 2017-05-14 23:38:52 -07:00
James R. Barlow 048ae40e75 Update copyrights 2017-05-14 23:38:28 -07:00
James R. Barlow 234183ecd2 Fix: Tesseract 3.04 is sensitive to order of configuration commands
“txt hocr” is not acceptable and does not produce expected output .txt
while “hocr text” works fine, so switch the order everywhere.

Should fix #169
2017-05-14 23:27:46 -07:00
James R. Barlow fb067dc97b cookbook: more on improving OCR 2017-05-14 23:16:47 -07:00
James R. Barlow a1fea0ce16 docs: link to OCRmyPDF-web 2017-05-14 23:16:30 -07:00
James R. Barlow e1e9135e93 Test suite: tidy up imports 2017-05-14 23:15:29 -07:00
James R. Barlow aff982036b autobrew: fix brew audit error on double blank line 2017-05-14 23:15:02 -07:00
James R. Barlow d087649eab Remove “null deploy script” since “/usr/bin/true” is equivalent 2017-05-12 15:37:02 -07:00
26 changed files with 98 additions and 50 deletions
+2 -2
View File
@@ -80,14 +80,14 @@ deploy:
# we really just want to run after_deploy *after* pypi upload is done, but
# after_deploy on runs if a given box deployed
- provider: script
script: .travis/null_deploy.sh
script: /usr/bin/true
on:
branch: master
tags: false
condition: $TRAVIS_OS_NAME == "osx"
after_deploy: |
if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then
if [[ "$TRAVIS_OS_NAME" == "osx" && "$TRAVIS_BRANCH" == "master" ]]; then
bash .travis/osx_brew.sh
elif [[ "$TRAVIS_PYTHON_VERSION" == "3.6" && "$TRAVIS_OS_NAME" == "linux" ]]; then
curl -H "Content-Type: application/json" --data '{"build": true}' -X POST https://registry.hub.docker.com/u/jbarlow83/ocrmypdf/trigger/$DOCKERHUB_OCRMYPDF_TOKEN/
+3 -1
View File
@@ -1,3 +1,6 @@
#!/usr/bin/env python3
# © 2016 James R. Barlow: github.com/jbarlow83
from string import Template
from subprocess import run, PIPE
import re
@@ -25,7 +28,6 @@ class Ocrmypdf < Formula
depends_on "libpng"
${resources}
def install
ENV.append ["SETUPTOOLS_SCM_PRETEND_VERSION"], "v${ocrmypdf_version}"
ENV.each do |key, value|
+1
View File
@@ -1,4 +1,5 @@
#!/bin/bash
# © 2017 James R. Barlow: github.com/jbarlow83
set -euo pipefail
set -x
-3
View File
@@ -1,3 +0,0 @@
#!/usr/bin/env bash
exit 0
+1
View File
@@ -1,4 +1,5 @@
#!/bin/bash
# © 2017 James R. Barlow: github.com/jbarlow83
set -euo pipefail
set -x
+1
View File
@@ -1,4 +1,5 @@
#!/bin/bash
# © 2017 James R. Barlow: github.com/jbarlow83
set -euo pipefail
set -x
+17 -2
View File
@@ -95,13 +95,19 @@ Use a program like `img2pdf <https://gitlab.mister-muffin.de/josch/img2pdf>`_ to
img2pdf my-images*.jpg | ocrmypdf - myfile.pdf
If given a single image as input, OCRmyPDF will try converting it to a PDF on its own. If the DPI specified in the image is incorrect, it can be overridden with ``--image-dpi``:
``img2pdf`` also has features to control the position of images on a page, if desired.
For convenience, OCRmyPDF can convert single images to PDFs on its own. If the resolution (dots per inch, DPI) of an image is not set or is incorrect, it can be overridden with ``--image-dpi``. (As 1 inch is 2.54 cm, 1 dpi = 0.39 dpcm).
.. code-block:: bash
ocrmypdf --image-dpi 300 image.png myfile.pdf
This feature may be removed at some point, because OCRmyPDF does not specialize in converting images to PDFs.
If you have multiple images, you must use ``img2pdf`` to convert the images to PDF.
.. note::
ImageMagick ``convert`` can also convert a group of images to PDF, but in the author's experience it takes a long time, transcodes unnecessarily and gives poor results.
You can also use Tesseract 3.04+ directly to convert single page images or multi-page TIFFs to PDF:
@@ -149,3 +155,12 @@ Image processing commands can be combined. The order in which options are given
ocrmypdf --deskew --clean --rotate-pages input.pdf output.pdf
Improving OCR quality
---------------------
The `Image processing`_ features can improve OCR quality.
Rotating pages and deskewing helps to ensure that the page orientation is correct before OCR begins. Removing the background and/or cleaning the page can also improve results. The ``--oversample DPI`` argument can be specified to resample images to higher resolution before attempting OCR; this can improve results as well.
OCR quality will suffer if the resolution of input images is not correct (since the range of pixel sizes that will be checked for possible fonts will also be incorrect).
+4 -1
View File
@@ -101,4 +101,7 @@ To the author's knowledge, OCRmyPDF is the most feature-rich and thoroughly test
* pdf2pdfocr
* pdfsandwich
* pypdfocr
* pdfbeads
* pdfbeads
If you are looking for a micro web-frontend for OCRmyPDF, consider the third-party `OCRmyPDF-web <https://github.com/sseemayer/OCRmyPDF-web>`_. Bear in mind that OCRmyPDF is not designed to be secure against malware-bearing PDFs (see `Using OCRmyPDF online`_).
+6
View File
@@ -4,6 +4,12 @@ Release notes
OCRmyPDF uses `semantic versioning <http://semver.org/>`_.
v5.0.1
------
- Fixed issue #169, exception due to failure to create sidecar text files on some versions of Tesseract 3.04, including the jbarlow83/ocrmypdf image
v5.0
----
+2
View File
@@ -1,3 +1,5 @@
# © 2017 James R. Barlow: github.com/jbarlow83
import pkg_resources
PROGRAM_NAME = 'ocrmypdf'
+1 -1
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env python3
# © 2015-16 James R. Barlow: github.com/jbarlow83
# © 2015-17 James R. Barlow: github.com/jbarlow83
from contextlib import suppress
from tempfile import mkdtemp
+1
View File
@@ -6,6 +6,7 @@ from subprocess import run, PIPE, STDOUT, CalledProcessError
from shutil import copy
from functools import lru_cache
import re
import sys
from . import get_program
from ..exceptions import SubprocessOutputError
+13 -16
View File
@@ -21,27 +21,22 @@ OrientationConfidence = namedtuple(
'OrientationConfidence',
('angle', 'confidence'))
HOCR_TEMPLATE = '''<?xml version="1.0" encoding="UTF-8"?>
HOCR_TEMPLATE = """<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name='ocr-system' content='tesseract 3.02.02' />
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<meta name='ocr-system' content='tesseract 3.05.00' />
<meta name='ocr-capabilities' content='ocr_page ocr_carea ocr_par ocr_line ocrx_word'/>
</head>
<body>
<div class='ocr_page' id='page_1' title='image "x.tif"; bbox 0 0 {0} {1}; ppageno 0'>
<div class='ocr_carea' id='block_1_1' title="bbox 0 1 {0} {1}">
<p class='ocr_par' dir='ltr' id='par_1' title="bbox 0 1 {0} {1}">
<span class='ocr_line' id='line_1' title="bbox 0 1 {0} {1}"><span class='ocrx_word' id='word_1' title="bbox 0 1 {0} {1}"> </span>
</span>
</p>
</div>
</head>
<body>
<div class='ocr_page' id='page_1' title='image "_blank.png"; bbox 0 0 {0} {1}; ppageno 0'>
</div>
</body>
</html>'''
</html>
"""
@lru_cache(maxsize=1)
@@ -229,11 +224,13 @@ def generate_hocr(input_file, output_files, language: list, engine_mode,
# Reminder: test suite tesseract spoofers will break after any changes
# to the number of order parameters here
# Tesseract 3.04 requires the order here to be "hocr txt" and will fail
# on "txt hocr"
args_tesseract.extend([
input_file,
prefix,
'txt',
'hocr'
'hocr',
'txt'
] + tessconfig)
try:
log.debug(args_tesseract)
@@ -316,8 +313,8 @@ def generate_pdf(*, input_image, skip_pdf, output_pdf, output_text,
args_tesseract.extend([
input_image,
prefix,
'txt',
'pdf',
'txt'
] + tessconfig)
try:
+1
View File
@@ -1 +1,2 @@
"""Bindings to external libraries"""
# © 2017 James R. Barlow: github.com/jbarlow83
+2
View File
@@ -1,3 +1,5 @@
# © 2017 James R. Barlow: github.com/jbarlow83
from cffi import FFI
ffibuilder = FFI()
+2
View File
@@ -1,4 +1,6 @@
#!/usr/bin/env python3
# © 2016 James R. Barlow: github.com/jbarlow83
import sys
import os
from subprocess import check_call
+2
View File
@@ -1,4 +1,6 @@
#!/usr/bin/env python3
# © 2016 James R. Barlow: github.com/jbarlow83
import sys
import os
+2
View File
@@ -1,4 +1,6 @@
#!/usr/bin/env python3
# © 2016 James R. Barlow: github.com/jbarlow83
import sys
import os
+2
View File
@@ -1,4 +1,6 @@
#!/usr/bin/env python3
# © 2016 James R. Barlow: github.com/jbarlow83
import sys
import os
+2
View File
@@ -1,4 +1,6 @@
#!/usr/bin/env python3
# © 2016 James R. Barlow: github.com/jbarlow83
import sys
+4 -2
View File
@@ -1,4 +1,6 @@
#!/usr/bin/env python3
# © 2016 James R. Barlow: github.com/jbarlow83
import sys
@@ -20,11 +22,11 @@ def main():
elif sys.argv[1] == '--list-langs':
print('List of available languages (1):\neng', file=sys.stderr)
sys.exit(0)
elif sys.argv[-1] == 'hocr':
elif sys.argv[-2] == 'hocr':
print("Image too large: (33830, 14959)\n"
"Error during processing.", file=sys.stderr)
sys.exit(1)
elif sys.argv[-1] == 'pdf':
elif sys.argv[-2] == 'pdf':
print("Image too large: (33830, 14959)\n"
"Error during processing.", file=sys.stderr)
sys.exit(1)
+19 -6
View File
@@ -1,4 +1,6 @@
#!/usr/bin/env python3
# © 2016 James R. Barlow: github.com/jbarlow83
import sys
import os
import hashlib
@@ -9,18 +11,27 @@ import subprocess
"""Cache output of tesseract to speed up test suite
The cache is keyed by a hash that includes the tesseract version, some of
the command line, and the binary dump of the input file. The output file,
stdout, and stderr are replicated on a cache hit.
the command line, and the binary dump of the input file, and this file itself.
Therefore any updates to this file invalidate cache. Uses SHA-1 because it is
fast and defeating a hash collision here is not exactly a priority. :P
The output files, stdout, and stderr are replicated on a cache hit. The output
files are either a .pdf and .txt or .hocr and .txt.
Page orientation checks are also cached (-psm 0 stdout)
Errors and crashes are not cached.
Errors and crashes are not cached. If the arguments don't match a known
caching template then real tesseract is called with the same arguments.
Things not checked:
-changes to tesseract installation that don't affect --version
Assumes Tesseract 3.04 or higher.
Will fail on Tesseract 3.02.02 in "hocr" mode because it doesn't produce
the incorrect file extension.
the incorrect file extension. Will fail on 3.03 because that has no sidecar
text support. Will fail to replicate a 3.04 bug if wrong parameter order is
given.
"""
@@ -35,10 +46,12 @@ def real_tesseract():
return # Not reachable
def main():
operation = sys.argv[-1]
operation = sys.argv[-2]
sidecar = False
if sys.argv[-2] == 'txt':
if sys.argv[-1] == 'txt':
sidecar = True
elif sys.argv[-1] == 'stdout':
operation = 'stdout'
# For anything unexpected operation, defer to real tesseract binary
# Currently this includes all use of "--tesseract-config"
+3 -2
View File
@@ -1,4 +1,5 @@
#!/usr/bin/env python3
# © 2016 James R. Barlow: github.com/jbarlow83
import sys
import os
import signal
@@ -28,10 +29,10 @@ def main():
elif sys.argv[1] == '--list-langs':
print('List of available languages (1):\neng', file=sys.stderr)
sys.exit(0)
elif sys.argv[-1] == 'hocr':
elif sys.argv[-2] == 'hocr':
print("KABOOM! Tesseract failed for some reason", file=sys.stderr)
sys.exit(128 + signal.SIGSEGV)
elif sys.argv[-1] == 'pdf':
elif sys.argv[-2] == 'pdf':
print("KABOOM! Tesseract failed for some reason", file=sys.stderr)
sys.exit(128 + signal.SIGSEGV)
elif sys.argv[-1] == 'stdout':
+3 -2
View File
@@ -1,4 +1,5 @@
#!/usr/bin/env python3
# © 2016 James R. Barlow: github.com/jbarlow83
import sys
import img2pdf
from PIL import Image
@@ -52,7 +53,7 @@ def main():
elif sys.argv[1] == '--list-langs':
print('List of available languages (1):\neng', file=sys.stderr)
sys.exit(0)
elif sys.argv[-1] == 'hocr':
elif sys.argv[-2] == 'hocr':
inputf = sys.argv[-4]
output = sys.argv[-3]
with Image.open(inputf) as im, \
@@ -61,7 +62,7 @@ def main():
f.write(HOCR_TEMPLATE.format(str(w), str(h)))
with open(output + '.txt', 'w') as f:
f.write('')
elif sys.argv[-1] == 'pdf':
elif sys.argv[-2] == 'pdf':
inputf = sys.argv[-4]
output = sys.argv[-3]
pdf_bytes = img2pdf.convert([inputf], dpi=300)
+1
View File
@@ -1,4 +1,5 @@
#!/usr/bin/env python3
# © 2016 James R. Barlow: github.com/jbarlow83
import sys
def main():
+3 -12
View File
@@ -4,8 +4,6 @@
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
@@ -13,6 +11,7 @@ from ocrmypdf.exceptions import ExitCode
from ocrmypdf import leptonica
from ocrmypdf.pdfa import file_claims_pdfa
from ocrmypdf.exec import ghostscript
import logging
check_ocrmypdf = pytest.helpers.check_ocrmypdf
@@ -78,13 +77,11 @@ def test_deskew(spoof_tesseract_noop, resources, outdir):
# Now render as an image again and use Leptonica to find the skew angle
# to confirm that it was deskewed
from ocrmypdf.exec.ghostscript import rasterize_pdf
import logging
log = logging.getLogger()
deskewed_png = outdir / 'deskewed.png'
rasterize_pdf(
ghostscript.rasterize_pdf(
str(deskewed_pdf),
str(deskewed_png),
xres=150,
@@ -119,13 +116,11 @@ def test_remove_background(spoof_tesseract_noop, resources, outdir):
'--image-dpi', '150',
env=spoof_tesseract_noop)
from ocrmypdf.exec.ghostscript import rasterize_pdf
import logging
log = logging.getLogger()
output_png = outdir / 'remove_bg.png'
rasterize_pdf(
ghostscript.rasterize_pdf(
str(output_pdf),
str(output_png),
xres=100,
@@ -271,10 +266,6 @@ def test_argsfile(spoof_tesseract_noop, resources, outdir):
def check_monochrome_correlation(
outdir,
reference_pdf, reference_pageno, test_pdf, test_pageno):
import ocrmypdf.exec.ghostscript as ghostscript
import logging
gslog = logging.getLogger()
reference_png = outdir / '{}.ref{:04d}.png'.format(