15

Runtime.getRuntime().exec()コマンドラインを使用してプログラム「tesseract」のインスタンスを実行するメソッドを使用するJavaプログラムを作成しようとしています。

背景として、Tesseract は無料のオープン ソース プログラムで、画像に対して OCR (光学式文字認識) を実行するために使用されます。画像ファイルを取り込み、テキストドキュメントを出力します。このコマンドを使用して実行するコマンドライン プログラムです。

(コマンド プロンプト シェル内から)

tesseract imageFilePath outFilePath [optional arguments] 

例:

tesseract "C:\Program Files (x86)\Tesseract-OCR\doc\eurotext.tif" "C:\Users\Dreadnought\Documents\TestingFolder\out"

最初の引数は tesseract プログラムを呼び出します。2 番目の引数は画像ファイルへの絶対パスで、最後の引数は出力ファイルのパスと名前です。Tesseract は出力ファイルの名前のみを必要とし、拡張子は必要ありません。

コマンドプロンプトから作業すると、これは完璧に機能します。ただし、これを Java プログラムから実行したかったのですが、いくつかのエラーが発生していました。

このコードは、出発点として非常に役立つことがわかりました

public class Main
{
   public static void main(String args[])
   {
      try
      {
         Runtime rt = Runtime.getRuntime();
         String cmdString = "cmd /c dir";

         System.out.println(cmdString);
         Process pr = rt.exec(cmdString);

         BufferedReader input = new BufferedReader(new InputStreamReader(
                                                   pr.getInputStream()));

         String line = null;

         while ((line = input.readLine()) != null)
         {
            System.out.println(line);
         }

         int exitVal = pr.waitFor();
         System.out.println("Exited with error code " + exitVal);

      }
      catch (Exception e)
      {
         System.out.println(e.toString());
         e.printStackTrace();
      }
   }
}

dir コマンドの結果を出力します。しかし、私がそれをそのように変更したとき

public class Main
{
   public static void main(String args[])
   {
      try
      {
         Runtime rt = Runtime.getRuntime();
         String imageFilePath = "\"C:\\Program Files (x86)\\Tesseract-OCR\\doc\\eurotext.tif\"";
         String outputFilePath = "\"C:\\Users\\Dreadnought\\Documents\\TestingFolder\\eurotext-example\"";
         String[] commands = {"cmd", "/c", "tesseract", imageFilePath, outputFilePath };

         Process pr = rt.exec(commands);

         BufferedReader input = new BufferedReader(new InputStreamReader(
               pr.getInputStream()));

         String line = null;

         while ((line = input.readLine()) != null)
         {
            System.out.println(line);
         }

         int exitVal = pr.waitFor();
         System.out.println("Exited with error code " + exitVal);
      }
      catch (Exception e)
      {
         System.out.println(e.toString());
         e.printStackTrace();
      }
   }
}

それが出力する唯一のものはExited with error code 1. Process がエラーで終了した場合、これは予想される出力です。

私も合格を試み"cmd /c tesseract \"C:\\Program Files (x86)\\Tesseract-OCR\\doc\\eurotext.tif\" \"C:\\Users\\Dreadnought\\Documents\\TestingFolder\\eurotext-example\""ましたが、結局同じエラーが発生しました。

Using quotes within getRuntime().execによると、問題は引用符をエスケープしようとしたことだと思ったので、文字列配列を渡しました。しかし、私はまだ取得していExited with error code 1ます。

javaコマンドでコマンドラインプログラムを実行することはできRuntime.getRuntime().exec()ますか?


編集:問題はまだ発生しています

Evgeniy Dorofeev と Nandkumar Tekale が以下に提案したのと同じ推論に沿って、"cmd /c" を使用しないようにしました。ただし、別の種類のエラーが発生します。

java.io.IOException: Cannot run program "tesseract": CreateProcess error=2, The system cannot find the file specified
java.io.IOException: Cannot run program "tesseract": CreateProcess error=2, The system  cannot find the file specified
    at java.lang.ProcessBuilder.start(Unknown Source)
    at java.lang.Runtime.exec(Unknown Source)
    at java.lang.Runtime.exec(Unknown Source)
    at Main.main(Main.java:15)
Caused by: java.io.IOException: CreateProcess error=2, The system cannot find the file specified
    at java.lang.ProcessImpl.create(Native Method)
    at java.lang.ProcessImpl.<init>(Unknown Source)
    at java.lang.ProcessImpl.start(Unknown Source)
... 4 more

多分これはより多くの情報を提供しますか?この問題の原因は何か、私は本当に興味があります。また、エスケープされた引用符を引数に追加するかどうかに関係なく、問題は同じです。


EDIT 2:気まぐれに、tesseract実行可能ファイルへの絶対パスを提供しcmd /c、魅力のように機能しませんでした。Runtime.getRuntime().exec()問題は、環境変数を呼び出せないことだと思いますか?

4

4 に答える 4

3

welltesseractは外部コマンドなので、一緒に使う必要はありませんcmdtesseract環境変数に追加します。次のように直接コマンドを使用します。

String[] commands = {"tesseract", imageFilePath, outputFilePath };

存在ステータス 1 は、機能が正しくないことを意味します。プロセスの終了ステータスを見る

于 2012-11-20T05:53:21.940 に答える
1

再コンパイルして展開する必要のない別の回避策は、古い DOS スタイルのパスを使用C:\Program FilesすることC:\Progra~1です。もちろん、これは、構成ファイルまたは DB およびレジストリなどからパスを読み取る場合にのみ役立ちます。

于 2013-05-02T15:23:46.190 に答える
1

別の回避策は、/usr/local/Cellar/tesseract/3.02.02/bin/tesseract のようなファイルの完全なインストール パスを指定することです"

于 2013-06-14T21:52:16.063 に答える