66435


以下のコード（任意のpdfファイルのOCR処理）をPython環境のないPCで実行できるよう、Pyinstallerでバイナリファイル（exe）を作成したのですが、作成したexeファイルが動作しません。（黒いコマンドプロンプトが一瞬起動してすぐ閉じる）。  
Anaconda prompt, PowerShell 等から実行すると以下のエラーが出ます。

[code]

    > ocr.exe
    Traceback (most recent call last):
      File "ocr.py", line 213, in <module>
    NameError: name 'null' is not defined
    [10656] Failed to execute script ocr
    
[/code]

どうすればexeファイルが動作するようになるでしょうか？  
また、コマンドラインからexeファイルを実行した時のエラー（line 213）を確認するにはどうすればよいでしょうか？

元のコードは以下の通りです。(環境：Windows 10、Python 3.6、Jupyter lab上で作成)

[code]

        %%time
    # coding: UTF-8
    from PIL import Image
    from pdf2image import convert_from_path
    from pathlib import Path
    import sys, os, pyocr, pyocr.builders, shutil, re, PyPDF2, tkinter, tkinter.filedialog, tkinter.messagebox, gc
    gc.collect()#memory節約のためにいったん解放
    
    # ファイル選択ダイアログの表示
    root = tkinter.Tk()#ダイアログ用のルートウィンドウの作成
    root.withdraw()
    root.attributes('-topmost', True)# topmost指定(最前面)
    root.withdraw()# ウィンドウを非表示に
    root.lift()#ダイアログを画面前面に持ってくる
    root.focus_force()#強制的に入力フォーカスをウィジェットに移動する
    
    fTyp = [("","*")]#選択肢として出すファイルタイプを指定　　fTyp = [("","*")] →　fTyp = [("","*.csv")]で拡張子限定
    
    iDir = os.path.abspath(os.path.dirname("__file__"))
    input_files = tkinter.filedialog.askopenfilenames(filetypes = fTyp,initialdir = iDir)
    
    #pyocrで使われるファイルのパス
    poppler_path = 'C:\\Users\\ilab2\\poppler-0.68.0\\bin'
    os.environ["PATH"] += os.pathsep + poppler_path
    
    #使用言語の確認
    tools = pyocr.get_available_tools()
    if len(tools) == 0:
        print("No OCR tool found")
        sys.exit(1)
    tool = tools[0]
    print("Will use tool '%s'" % (tool.get_name()))
    langs = tool.get_available_languages()
    print("Available languages: %s" % ", ".join(langs))
    lang = langs
    print("Will use lang '%s'" % (lang))
    
    #処理ファイルの入力
    #input_file = input('ファイルのパスを入力してください。')
    
    for input_file in input_files:
        texts = []
        png_names = []
        pdf_names = []
        txt_file =[]
        if '.pdf' in input_file:
    
            pdf_path = Path(input_file)
            pdf_path = Path(input_file)
            image_dir = Path(input_file)    
            #pdfをpngファイルに変換
            pages = convert_from_path(input_file, grayscale = True, dpi = 600)
    
            for page in pages:
                txt = tool.image_to_string(
                    page,
                    lang=langs[1:2],
                    builder=pyocr.builders.TextBuilder(tesseract_layout=3)
                )
                file_name = pdf_path.stem + "_{:02d}".format(pages.index(page)) + ".png"
                image_path = file_name
            # pngで保存
                page.save(str(file_name), "png")
                png_names.append(str(file_name))
                #繰り返し処理の結果をリストに追加
                #コマンドラインとして実行するために新しいファイル名となる変数をあらかじめ作成
                new= "ocr_" + file_name
    
                #config fileがない場合は-cオプションを使う
                !tesseract -l eng+jpn -c tessedit_create_pdf=1 {file_name} {new}
               # !tesseract -l eng+jpn -c tessedit_create_txt=1 {file_name} {new}
    
                pdf_names.append(new + ".pdf")
                del txt
                gc.collect()#memory節約のためにいったん解放
                #txt_file.append(new + ".txt")
                #texts.append(txt)
    
            #pdfを一つに結合
            pdf_writer = PyPDF2.PdfFileWriter()
            for name in pdf_names:
                pdf_reader = PyPDF2.PdfFileReader(str(name))
                for i in range(pdf_reader.getNumPages()):
                    pdf_writer.addPage(pdf_reader.getPage(i))
    
            # 保存ファイル名
            merged_file = "done_" + file_name+".pdf"
            # 保存
            with open(merged_file, "wb") as f:
                pdf_writer.write(f)
    
            #txtファイルを統合
         #   with open("ocr.txt", "wb", encoding='UTF-8') as outfile:
             #   for txt in txt_file:
                    #with open(txt, "rb", encoding='UTF-8') as infile:
                      #  outfile.write(infile.read())
    
                #ばらばらのファイルを削除
            for file in png_names:
                os.remove(file)
            for file in pdf_names:
                os.remove(file)
           # for file in txt_file:
             #   os.remove(file)
            del pdf_names#リストも削除しないと2巡目以降のpdf統合でerror
    
        gc.collect()#memory節約のためにいったん解放
    
[/code]

exe化した時のコードは以下の通りです（Anaconda promptで実行)

[code]

     >pyinstaller test.py --clean --debug all
    85 INFO: PyInstaller: 3.6
    86 INFO: Python: 3.6.10 (conda)
    87 INFO: Platform: Windows-10-10.0.17763-SP0
    92 INFO: wrote C:\Users\ilab2\test.spec
    94 INFO: UPX is not available.
    94 INFO: Removing temporary files and cleaning cache in C:\Users\ilab2\AppData\Roaming\pyinstaller
    106 INFO: Extending PYTHONPATH with paths
    ['C:\\Users\\ilab2', 'C:\\Users\\ilab2']
    107 INFO: checking Analysis
    110 INFO: Building Analysis because Analysis-00.toc is non existent
    110 INFO: Initializing module dependency graph...
    117 INFO: Caching module graph hooks...
    128 INFO: Analyzing base_library.zip ...
    4074 INFO: Caching module dependency graph...
    4174 INFO: running Analysis Analysis-00.toc
    4200 INFO: Adding Microsoft.Windows.Common-Controls to dependent assemblies of final executable
      required by C:\Users\ilab2\anaconda3\envs\py36\python.exe
    4590 INFO: Analyzing C:\Users\ilab2\test.py
    4593 INFO: Processing module hooks...
    4594 INFO: Loading module hook "hook-encodings.py"...
    4702 INFO: Loading module hook "hook-pydoc.py"...
    4703 INFO: Loading module hook "hook-xml.py"...
    5022 INFO: Looking for ctypes DLLs
    5022 INFO: Analyzing run-time hooks ...
    5030 INFO: Looking for dynamic libraries
    5126 INFO: Looking for eggs
    5126 INFO: Using Python library C:\Users\ilab2\anaconda3\envs\py36\python36.dll
    5128 INFO: Found binding redirects:
    []
    5190 INFO: Warnings written to C:\Users\ilab2\build\test\warn-test.txt
    5237 INFO: Graph cross-reference written to C:\Users\ilab2\build\test\xref-test.html
    5247 INFO: checking PYZ
    5247 INFO: Building PYZ because PYZ-00.toc is non existent
    5247 INFO: Building PYZ (ZlibArchive) C:\Users\ilab2\build\test\PYZ-00.pyz
    5248 INFO: Building PYZ (ZlibArchive) C:\Users\ilab2\build\test\PYZ-00.pyz completed successfully.
    5254 INFO: checking PKG
    5254 INFO: Building PKG because PKG-00.toc is non existent
    5255 INFO: Building PKG (CArchive) PKG-00.pkg
    5270 INFO: Building PKG (CArchive) PKG-00.pkg completed successfully.
    5273 INFO: Bootloader C:\Users\ilab2\anaconda3\envs\py36\lib\site-packages\PyInstaller\bootloader\Windows-64bit\run_d.exe
    5273 INFO: checking EXE
    5278 INFO: Building EXE because EXE-00.toc is non existent
    5279 INFO: Building EXE from EXE-00.toc
    5279 INFO: Appending archive to EXE C:\Users\ilab2\build\test\test.exe
    5289 INFO: Building EXE from EXE-00.toc completed successfully.
    5293 INFO: checking COLLECT
    5293 INFO: Building COLLECT because COLLECT-00.toc is non existent
    5294 INFO: Building COLLECT COLLECT-00.toc
    6898 INFO: Building COLLECT COLLECT-00.toc completed successfully.
    
[/code]

pyinstallerによるexe化の際に生成されるspecファイルの中身は以下の通りです。

[code]

    # -*- mode: python ; coding: utf-8 -*-
    
    block_cipher = None
    
    
    a = Analysis(['test.py'],
                 pathex=['C:\\Users\\ilab2\\dist'],
                 binaries=[],
                 datas=[],
                 hiddenimports=[],
                 hookspath=[],
                 runtime_hooks=[],
                 excludes=[],
                 win_no_prefer_redirects=False,
                 win_private_assemblies=False,
                 cipher=block_cipher,
                 noarchive=True)
    pyz = PYZ(a.pure, a.zipped_data,
                 cipher=block_cipher)
    exe = EXE(pyz,
              a.scripts,
              [('v', None, 'OPTION')],
              exclude_binaries=True,
              name='test',
              debug=True,
              bootloader_ignore_signals=False,
              strip=False,
              upx=True,
              console=True )
    coll = COLLECT(exe,
                   a.binaries,
                   a.zipfiles,
                   a.datas,
                   strip=False,
                   upx=True,
                   upx_exclude=[],
                   name='test')
    
[/code]

pyinstallerの生成したexeファイルをAnaconda promptから実行した結果が以下になります。

[code]

    >test.exe
    [3084] PyInstaller Bootloader 3.x
    [3084] LOADER: executable is C:\Users\ilab2\dist\test.exe
    [3084] LOADER: homepath is C:\Users\ilab2\dist
    [3084] LOADER: _MEIPASS2 is NULL
    [3084] LOADER: archivename is C:\Users\ilab2\dist\test.exe
    [3084] LOADER: Extracting binaries
    [3084] LOADER: Executing self as child
    [3084] LOADER: set _MEIPASS2 to C:\Users\ilab2\AppData\Local\Temp\_MEI30842
    [3084] LOADER: Setting up to run child
    [3084] LOADER: Creating child process
    [3084] LOADER: Waiting for child process to finish...
    [6188] PyInstaller Bootloader 3.x
    [6188] LOADER: executable is C:\Users\ilab2\dist\test.exe
    [6188] LOADER: homepath is C:\Users\ilab2\dist
    [6188] LOADER: _MEIPASS2 is C:\Users\ilab2\AppData\Local\Temp\_MEI30842
    [6188] LOADER: archivename is C:\Users\ilab2\dist\test.exe
    [6188] LOADER: SetDllDirectory(C:\Users\ilab2\AppData\Local\Temp\_MEI30842)
    [6188] LOADER: Already in the child - running user's code.
    [6188] LOADER: manifestpath: C:\Users\ilab2\AppData\Local\Temp\_MEI30842\test.exe.manifest
    [6188] LOADER: Activation context created
    [6188] LOADER: Activation context activated
    [6188] LOADER: ucrtbase.dll is exists: C:\Users\ilab2\AppData\Local\Temp\_MEI30842\ucrtbase.dll
    [6188] LOADER: Python library: C:\Users\ilab2\AppData\Local\Temp\_MEI30842\python36.dll
    [6188] LOADER: Loaded functions from Python library.
    [6188] LOADER: Manipulating environment (sys.path, sys.prefix)
    [6188] LOADER: sys.prefix is C:\Users\ilab2\AppData\Local\Temp\_MEI30842
    [6188] LOADER: Pre-init sys.path is C:\Users\ilab2\AppData\Local\Temp\_MEI30842\base_library.zip;C:\Users\ilab2\AppData\Local\Temp\_MEI30842
    [6188] LOADER: Setting runtime options
    [6188] LOADER: Bootloader option: pyi-windows-manifest-filename test.exe.manifest
    [6188] LOADER: Runtime option: v
    [6188] LOADER: Initializing python
    import _frozen_importlib # frozen
    import _imp # builtin
    import sys # builtin
    import '_warnings' # <class '_frozen_importlib.BuiltinImporter'>
    import '_thread' # <class '_frozen_importlib.BuiltinImporter'>
    import '_weakref' # <class '_frozen_importlib.BuiltinImporter'>
    import '_frozen_importlib_external' # <class '_frozen_importlib.FrozenImporter'>
    import '_io' # <class '_frozen_importlib.BuiltinImporter'>
    import 'marshal' # <class '_frozen_importlib.BuiltinImporter'>
    import 'nt' # <class '_frozen_importlib.BuiltinImporter'>
    import _thread # previously loaded ('_thread')
    import '_thread' # <class '_frozen_importlib.BuiltinImporter'>
    import _weakref # previously loaded ('_weakref')
    import '_weakref' # <class '_frozen_importlib.BuiltinImporter'>
    import 'winreg' # <class '_frozen_importlib.BuiltinImporter'>
    # installing zipimport hook
    import 'zipimport' # <class '_frozen_importlib.BuiltinImporter'>
    # installed zipimport hook
    # zipimport: found 150 names in 'C:\\Users\\ilab2\\AppData\\Local\\Temp\\_MEI30842\\base_library.zip'
    import '_codecs' # <class '_frozen_importlib.BuiltinImporter'>
    import codecs # loaded from Zip C:\Users\ilab2\AppData\Local\Temp\_MEI30842\base_library.zip\codecs.pyc
    import encodings.aliases # loaded from Zip C:\Users\ilab2\AppData\Local\Temp\_MEI30842\base_library.zip\encodings\aliases.pyc
    import encodings # loaded from Zip C:\Users\ilab2\AppData\Local\Temp\_MEI30842\base_library.zip\encodings\__init__.pyc
    import encodings.utf_8 # loaded from Zip C:\Users\ilab2\AppData\Local\Temp\_MEI30842\base_library.zip\encodings\utf_8.pyc
    import '_signal' # <class '_frozen_importlib.BuiltinImporter'>
    import encodings.latin_1 # loaded from Zip C:\Users\ilab2\AppData\Local\Temp\_MEI30842\base_library.zip\encodings\latin_1.pyc
    import _weakrefset # loaded from Zip C:\Users\ilab2\AppData\Local\Temp\_MEI30842\base_library.zip\_weakrefset.pyc
    import abc # loaded from Zip C:\Users\ilab2\AppData\Local\Temp\_MEI30842\base_library.zip\abc.pyc
    import io # loaded from Zip C:\Users\ilab2\AppData\Local\Temp\_MEI30842\base_library.zip\io.pyc
    [6188] LOADER: Overriding Python's sys.path
    [6188] LOADER: Post-init sys.path is C:\Users\ilab2\AppData\Local\Temp\_MEI30842\base_library.zip;C:\Users\ilab2\AppData\Local\Temp\_MEI30842
    [6188] LOADER: Setting sys.argv
    [6188] LOADER: setting sys._MEIPASS
    [6188] LOADER: importing modules from CArchive
    [6188] LOADER: extracted struct
    [6188] LOADER: callfunction returned...
    import '_struct' # <class '_frozen_importlib.BuiltinImporter'>
    [6188] LOADER: extracted pyimod01_os_path
    [6188] LOADER: callfunction returned...
    [6188] LOADER: extracted pyimod02_archive
    [6188] LOADER: callfunction returned...
    import 'zlib' # <class '_frozen_importlib.BuiltinImporter'>
    [6188] LOADER: extracted pyimod03_importers
    [6188] LOADER: callfunction returned...
    [6188] LOADER: Installing PYZ archive with Python modules.
    [6188] LOADER: PYZ archive: PYZ-00.pyz
    [6188] LOADER: Running pyiboot01_bootstrap.py
    # PyInstaller: FrozenImporter(C:\Users\ilab2\dist\test.exe?6383816)
    # os not found in PYZ
    # code object from 'C:\\Users\\ilab2\\AppData\\Local\\Temp\\_MEI30842\\os.pyc'
    import 'errno' # <class '_frozen_importlib.BuiltinImporter'>
    # stat not found in PYZ
    # code object from 'C:\\Users\\ilab2\\AppData\\Local\\Temp\\_MEI30842\\stat.pyc'
    import '_stat' # <class '_frozen_importlib.BuiltinImporter'>
    import 'stat' # <_frozen_importlib_external.SourcelessFileLoader object at 0x000002605DD21908>
    # ntpath not found in PYZ
    # code object from 'C:\\Users\\ilab2\\AppData\\Local\\Temp\\_MEI30842\\ntpath.pyc'
    # genericpath not found in PYZ
    # code object from 'C:\\Users\\ilab2\\AppData\\Local\\Temp\\_MEI30842\\genericpath.pyc'
    import 'genericpath' # <_frozen_importlib_external.SourcelessFileLoader object at 0x000002605DD2B780>
    import 'ntpath' # <_frozen_importlib_external.SourcelessFileLoader object at 0x000002605DD21F60>
    # _collections_abc not found in PYZ
    import _collections_abc # loaded from Zip C:\Users\ilab2\AppData\Local\Temp\_MEI30842\base_library.zip\_collections_abc.pyc
    import 'os' # <_frozen_importlib_external.SourcelessFileLoader object at 0x000002605DD0B630>
    # ctypes not found in PYZ
    [6188] LOADER: Running test.py
    [6188] LOADER: OK.
    [6188] LOADER: Cleaning up Python interpreter.
    # clear builtins._
    # clear sys.path
    # clear sys.argv
    # clear sys.ps1
    # clear sys.ps2
    # clear sys.last_type
    # clear sys.last_value
    # clear sys.last_traceback
    # clear sys.path_hooks
    # clear sys.path_importer_cache
    # clear sys.meta_path
    # clear sys.__interactivehook__
    # clear sys.flags
    # clear sys.float_info
    # restore sys.stdin
    # restore sys.stdout
    # restore sys.stderr
    # cleanup[2] removing builtins
    # cleanup[2] removing sys
    # cleanup[2] removing _frozen_importlib
    # cleanup[2] removing _imp
    # cleanup[2] removing _warnings
    # cleanup[2] removing _thread
    # cleanup[2] removing _weakref
    # cleanup[2] removing _frozen_importlib_external
    # cleanup[2] removing _io
    # cleanup[2] removing marshal
    # cleanup[2] removing nt
    # cleanup[2] removing winreg
    # cleanup[2] removing zipimport
    # cleanup[2] removing encodings
    # cleanup[2] removing codecs
    # cleanup[2] removing _codecs
    # cleanup[2] removing encodings.aliases
    # cleanup[2] removing encodings.utf_8
    # cleanup[2] removing _signal
    # cleanup[2] removing __main__
    # destroy __main__
    # cleanup[2] removing encodings.latin_1
    # cleanup[2] removing io
    # destroy io
    # cleanup[2] removing abc
    # cleanup[2] removing _weakrefset
    # destroy _weakrefset
    # cleanup[2] removing struct
    # cleanup[2] removing _struct
    # cleanup[2] removing pyimod01_os_path
    # cleanup[2] removing pyimod02_archive
    # cleanup[2] removing zlib
    # cleanup[2] removing pyimod03_importers
    # cleanup[2] removing os
    # cleanup[2] removing errno
    # cleanup[2] removing stat
    # cleanup[2] removing _stat
    # cleanup[2] removing ntpath
    # cleanup[2] removing genericpath
    # cleanup[2] removing os.path
    # cleanup[2] removing _collections_abc
    # destroy _collections_abc
    # destroy zipimport
    # destroy _signal
    # destroy encodings
    # destroy abc
    # destroy errno
    # destroy ntpath
    # destroy _stat
    # destroy genericpath
    # destroy os
    # destroy stat
    # cleanup[3] wiping _frozen_importlib
    # destroy _frozen_importlib_external
    # cleanup[3] wiping _imp
    # cleanup[3] wiping _warnings
    # cleanup[3] wiping _thread
    # cleanup[3] wiping _weakref
    # cleanup[3] wiping _io
    # cleanup[3] wiping marshal
    # cleanup[3] wiping nt
    # cleanup[3] wiping winreg
    # cleanup[3] wiping codecs
    # cleanup[3] wiping _codecs
    # cleanup[3] wiping encodings.aliases
    # cleanup[3] wiping encodings.utf_8
    # cleanup[3] wiping encodings.latin_1
    # cleanup[3] wiping struct
    # cleanup[3] wiping _struct
    # destroy _struct
    # cleanup[3] wiping pyimod01_os_path
    # cleanup[3] wiping pyimod02_archive
    # cleanup[3] wiping zlib
    # destroy zlib
    # cleanup[3] wiping pyimod03_importers
    # cleanup[3] wiping sys
    # cleanup[3] wiping builtins
    # destroy _imp
    # destroy io
    # destroy _warnings
    # destroy nt
    # destroy _thread
    # destroy _weakref
    # destroy winreg
    # destroy _frozen_importlib
    [3084] LOADER: Back to parent (RC: 0)
    [3084] LOADER: Doing cleanup
    [3084] LOADER: Freeing archive status for C:\Users\ilab2\dist\test.exe
    
[/code]


CC BY-SA 4.0
2020-05-06T20:02:20.287
66359
2020-07-11T16:56:42.577
2020-07-11T16:56:42.577
3060
39973
question
python python3 pyinstaller
Pyinstallerでexeファイル化したが動作しない


Anaconda環境でやってみたけれど動かすことが出来なかったので、素のPythonに切り替えて動かしてみました。そのため幾つか版数が変わっていて、以下になっています。

  * 素の64bit Python 3.6.8, pyocr 0.7.2, Pillow 7.1.2, pdf2image 1.13.1, PyPDF2 1.26.0, PyInstaller 3.6
  * tesseract 5.0.0-alpha.20200328, poppler-0.68.0, poppler-data-0.4.9

tesseract 5.0.0-alpha.20200328は`C:\Program Files\tesseract-
OCR`フォルダにインストールし、データは`C:\Program Files\tesseract-
OCR\tessdata`に入ったものを`C:\Program Files\tesseract-
OCR\data`を作ってコピーし、さらにその配下に空の`tessdata`フォルダを作っています。  
poppler-0.68.0は`C:\Program Files (x86)\poppler`フォルダにインストールしています。

* * *

こんな感じでソースコードに変更を加えています。

  * `tesseract`の実行を`JupyterLab`の`!`コマンドから`subprocess.run`に変更
  * 冒頭の`import`記述を整理
  * `PyInstaller`でexe化すると、`tesseract`の実行ファイルとデータファイルのデフォルトパスが作成したexeの配下に変わったので、その対処を追加
  * .png化/テキスト認識/再.pdf化等の処理を対象ファイルのあるフォルダに移動して行うように変更
  * 上記各処理の作業ファイル名作成・指定処理を整理

* * *

`PyInstaller`でexe化後にtesseractのプログラム＆データ用にフォルダを作って元のところからファイルをコピーしています。

[code]

    元のスクリプトのあるフォルダ
      |
      +- dist
          |
          +- exe化スクリプト名フォルダ
              |
              +- PIL/tcl/tkといったフォルダ有り(exe化時に自動的に作成)
              |
              +- tesseract 作成してC:\Program Files\tesseract-OCRからコピー
              |
              +- data 作成してC:\Program Files\tesseract-OCR\tessdataからコピー
                  |
                  +- config/script/tessconfigsといったフォルダ(同様に上記からコピー)
                  |
                  +- tessdata  (空フォルダを作成)
    
[/code]

このような変更と環境構築により、素のPythonからスクリプトで実行しても、exe化したものを実行した場合でも同様に問題無く動作するようになりました。

* * *

変更したソースコードは以下になります。`####`のコメントを付けた所が主な変更点です。

[code]

    # coding: UTF-8
    import gc
    import os
    import shutil
    import sys
    import re
    from pathlib import Path
    #### JupyterLab の ! コマンドではなく subprocess.run で tesseract を実行する
    import subprocess
    import tkinter
    import tkinter.filedialog
    import tkinter.messagebox
    
    from PIL import Image
    from pdf2image import convert_from_path
    import pyocr
    import pyocr.builders
    import PyPDF2
    
    gc.collect()#memory節約のためにいったん解放
    
    # ファイル選択ダイアログの表示
    root = tkinter.Tk()#ダイアログ用のルートウィンドウの作成
    root.withdraw()
    root.attributes('-topmost', True)# topmost指定(最前面)
    root.withdraw()# ウィンドウを非表示に
    root.lift()#ダイアログを画面前面に持ってくる
    root.focus_force()#強制的に入力フォーカスをウィジェットに移動する
    
    #### 実行ファイルのフォルダ：PyInstallerコンパイルかスクリプト実行か
    is_frozen = hasattr(sys, "frozen")
    executable_dir = Path(sys.argv[0] if is_frozen else __file__).resolve().parent
    
    fTyp = [("","*")]#選択肢として出すファイルタイプを指定　　fTyp = [("","*")] →　fTyp = [("","*.csv")]で拡張子限定
    input_files = tkinter.filedialog.askopenfilenames(filetypes = fTyp,initialdir = executable_dir)
    
    #### PyInstallerコンパイルかスクリプト実行かで使うフォルダが変わる
    # pyocrで使われるtesseract, popplerのbinパス
    tesseract_path = executable_dir / 'tesseract' if is_frozen else Path(r'C:\Program Files\tesseract-OCR')
    poppler_path = r'C:\Program Files (x86)\poppler\bin'
    
    path_list = os.environ["PATH"].split(os.pathsep)
    if tesseract_path not in path_list:
        os.environ["PATH"] += os.pathsep + str(tesseract_path)
    if poppler_path not in path_list:
        os.environ["PATH"] += os.pathsep + poppler_path
    
    # pyocrで使われるtesseractのdataパス
    if is_frozen:
        os.environ["TESSDATA_PREFIX"] = str(executable_dir / 'data')
    else:
        tessdata_path = r'C:\Program Files\tesseract-OCR\data'
        try:
            current_data = os.environ["TESSDATA_PREFIX"]
        except:
            os.environ["TESSDATA_PREFIX"] = tessdata_path
    
    # 使用言語の確認
    tools = pyocr.get_available_tools()
    if len(tools) == 0:
        print("No OCR tool found")
        sys.exit(1)
    tool = tools[0]
    print("Will use tool '%s'" % (tool.get_name()))
    langs = tool.get_available_languages()
    print("Available languages: %s" % ", ".join(langs))
    lang = langs
    print("Will use lang '%s'" % (lang))
    
    # 指定ファイルの処理
    for input_file in input_files:
        texts = []
        png_names = []
        pdf_names = []
        txt_file =[]
        if '.pdf' in input_file:
    
            pdf_path = Path(input_file)
            image_dir = Path(input_file)
            #### カレントフォルダをファイルのある場所に移動して拡張子無しのファイル名を記憶
            os.chdir(pdf_path.parent)  ####
            base_file = pdf_path.stem  ####
            #pdfをpngファイルに変換
            pages = convert_from_path(input_file, grayscale = True, dpi = 600)
    
            for page in pages:
                #### テキスト化の対象言語指定lang=はPDF化処理と合わせる
                txt = tool.image_to_string(
                    page,
                    lang="eng+jpn",
                    builder=pyocr.builders.TextBuilder(tesseract_layout=3)
                )
                #### ページ毎の .png , .pdf のファイル名指定を整理
                page_name = base_file + "_{:02d}".format(pages.index(page))  ####
                image_path = page_name + ".png"  ####
                # pngで保存
                page.save(str(image_path), "png")  ####
                png_names.append(str(image_path))  ####
                #繰り返し処理の結果をリストに追加
                #config fileがない場合は-cオプションを使う
                #### JupyterLab の ! コマンドではなく subprocess.run で tesseract を実行する
                subprocess.run(["tesseract", image_path, page_name,
                                "-l", "eng+jpn", "-c", "tessedit_create_pdf=1", "pdf"])
    
                pdf_names.append(page_name + ".pdf")  ####
                del txt
                gc.collect()#memory節約のためにいったん解放
                #txt_file.append(new + ".txt")
                #texts.append(txt)
    
            #pdfを一つに結合
            pdf_writer = PyPDF2.PdfFileWriter()
            for name in pdf_names:
                pdf_reader = PyPDF2.PdfFileReader(str(name))
                for i in range(pdf_reader.getNumPages()):
                    pdf_writer.addPage(pdf_reader.getPage(i))
    
            # 保存ファイル名
            merged_file = "done_" + base_file + ".pdf"  ####
            # 保存
            with open(merged_file, "wb") as f:
                pdf_writer.write(f)
    
            #txtファイルを統合
         #   with open("ocr.txt", "wb", encoding='UTF-8') as outfile:
             #   for txt in txt_file:
                    #with open(txt, "rb", encoding='UTF-8') as infile:
                      #  outfile.write(infile.read())
    
                #ばらばらのファイルを削除
            for file in png_names:
                os.remove(file)
            for file in pdf_names:
                os.remove(file)
           # for file in txt_file:
             #   os.remove(file)
            del pdf_names#リストも削除しないと2巡目以降のpdf統合でerror
    
        gc.collect()#memory節約のためにいったん解放
    
[/code]


CC BY-SA 4.0
2020-05-08T12:42:54.157
66435
2020-05-08T12:42:54.157
26370
66359
answer