Search code examples
javainputstreamstdinbufferedimageoutputstream

How to change stdin when using Runtime class in JAVA


I want to use tesseract to recognize some text and I will use Runtime class to exec system command. Here, I want to use stdin to input my img ,rather than reading a file.

    private String preprocessCmdCommand(BufferedImage img) throws IOException, InterruptedException {
        String cmd = "D:\\Program Files\\Tesseract-OCR\\tesseract.exe stdin output -l chi_sm";
        Runtime run = Runtime.getRuntime();
        try {
            Process p = run.exec(cmd);
            // Write to the standard input stream
            OutputStream stdin = p.getOutputStream();
            stdin.write(HelpFunction.getImageBinary(img, "png")); //(TesseractOcr.java:40)
            InputStream stdout = p.getInputStream();
            consumeInputStream(stdout);

            if (p.waitFor() != 0) {
                if (p.exitValue() == 1)
                    System.err.println("fail!");
            }
        } catch (IOException | InterruptedException e) {
            e.printStackTrace();
        }
        return null;
    }

I tried the method suggested by the first answer , but I got an exception .

java.io.IOException: pipe is closing
    at java.base/java.io.FileOutputStream.writeBytes(Native Method)
    at java.base/java.io.FileOutputStream.write(FileOutputStream.java:347)
    at java.base/java.io.BufferedOutputStream.write(BufferedOutputStream.java:123)
    at java.base/java.io.FilterOutputStream.write(FilterOutputStream.java:108)
    at ocr_processor.TesseractOcr.preprocessCmdCommand(TesseractOcr.java:40)
    at ocr_processor.TesseractOcr.recognizeSingleText(TesseractOcr.java:57)
    at Test.testOrientFunction(Test.java:32)
    at Test.main(Test.java:42)
[INFO ] 2020-07-16 08:57:42,783 method:Test.testOrientFunction(Test.java:32)

My platform is windows 10 , Java SDK is 14.0.1.


Solution

  • Well today I get an idea from other questions. I finally use the following code to achieve my target!

            Runtime runtime = Runtime.getRuntime();
            try {
                Process process = runtime.exec("cmd /c tesseract stdin stdout");
                OutputStream os = process.getOutputStream();
                os.write(util.HelpFunction.getBinaryImage(img));
                os.close();
                consumeInputStream(process.getInputStream());
                int exitVal = process.exitValue();
                System.out.println("process exit value is " + exitVal);
            } catch (IOException e) {
                e.printStackTrace();
            }
    

    Thanks for helping me ! :)