Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/go/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
从java进程调用jpegoptim和pngquant,在标准文本中传递图像,并在标准文本中读取结果:断管或挂起_Java_Bash_Image Processing - Fatal编程技术网

从java进程调用jpegoptim和pngquant,在标准文本中传递图像,并在标准文本中读取结果:断管或挂起

从java进程调用jpegoptim和pngquant,在标准文本中传递图像,并在标准文本中读取结果:断管或挂起,java,bash,image-processing,Java,Bash,Image Processing,我有一个jpeg或png类型的变量中的imagen,我正在尝试通过Java1.6使用命令行jpegoptim或pngquant转换它 问题是我不能让它工作。我读了很多答案,但没有找到答案 这是我尝试的最后一个函数: public int execute(byte[] image) throws IOException { ProcessBuilder processBuilder = new ProcessBuilder(commandLine); final Process p

我有一个jpeg或png类型的变量中的imagen,我正在尝试通过Java1.6使用命令行jpegoptim或pngquant转换它

问题是我不能让它工作。我读了很多答案,但没有找到答案

这是我尝试的最后一个函数:

public int execute(byte[] image) throws IOException {
    ProcessBuilder processBuilder = new ProcessBuilder(commandLine);
    final Process process = processBuilder.start();
    final ByteArrayOutputStream outputBuffer = new ByteArrayOutputStream();
    final ByteArrayOutputStream errorBuffer = new ByteArrayOutputStream();

    try {
        // Handle stdout...
        new Thread() {
            public void run() {
                try {
                    IOUtils.copy(process.getInputStream(), outputBuffer);
                } catch (Exception e) {
                    LOG.error("Error executing " + commandLine,e);
                }
            }
        }.start();

        // Handle sderr...
        new Thread() {
            public void run() {
                try {
                    IOUtils.copy(process.getErrorStream(), errorBuffer);
                } catch (Exception e) {
                    LOG.error("Error executing " + commandLine,e);
                }
            }
        }.start();

        process.getOutputStream().write(image);
        process.getOutputStream().flush();
        process.waitFor();

        result = outputBuffer.toByteArray();
        errorMsg = errorBuffer.toString("ASCII");

    } catch (InterruptedException e) {
        LOG.error("Error executing " + commandLine,e);
    } finally {
        if( process != null ) {
            close(process.getErrorStream());
            close(process.getOutputStream());
            close(process.getInputStream());
            process.destroy();
        }
    }
    return process.exitValue();
}
命令行用于jpg:

this.commandLine = new ArrayList<String>();
this.commandLine.add("jpegoptim");
this.commandLine.add("-m90");
this.commandLine.add("--stdout");
this.commandLine.add("--stdin");
等待永远不会回来。。。少了什么

如果我在刷新(在上面的代码中注释)之后放入“stdin.close();”,则进程结束。但是stdout没有被完全处理,并且显示了一个错误:java.io.IOException:Stream关闭两次(每个线程一次)。logfile.log与映像相同,但标准输出被截断

我通过命令行对此进行测试:

java-cp testProc.jar testProc.Test image.jpg>image\u new.jpg

logfile.log等于image.jpg image_new.jpg更小,是image.jpg的截断版本


有什么线索吗?

从最后两行开始。您不能使用
>stdin
通过
stdin
。查看一些ProcessBuilder示例,了解如何使用BufferedWriter写入进程的stdin(Java进程的stdout),然后使用BufferedReader对子进程的stdout执行同样的操作。
如果在这之后仍然存在问题,那么为了进行诊断,您可以尝试用
tee-a日志文件
替换
jpegoptim
pngquant
,它将获取stdin并将其直接传输回stdout(和一个名为logfile的文件)。
然后您就得到了一个包含所有管道数据的文件,或者您将得到一个空文件和管道错误,因为您的Java程序没有传入数据,您可以查看它是否正确。
如果您得到一个包含数据的文件,并且没有管道错误,这可能意味着
jpegoptim
没有返回任何数据。
此时,您可以通过管道将数据从
logfile
传输到命令行上的
jpegoptim
,并使用这些选项,直到它正常工作,然后在Java代码中使用这些工作选项。

最后,我让它正常工作了

我纯粹靠运气找到了解决办法!。。。 我取消了那句台词:

stdin.close();
并在“process.waitFor();”行之后添加:这几行:

errorT.join();
outputT.join();
要处理图像,命令如下:

commandLine.add("jpegoptim");
commandLine.add("-m90");
commandLine.add("--stdout");
commandLine.add("--stdin");
以及:

最终代码:

public int execute(List<String> commandLine, byte[] image) throws IOException {

    ProcessBuilder processBuilder = new ProcessBuilder(commandLine);

    final Process process = processBuilder.start();

    OutputStream stdin = process.getOutputStream ();
    final InputStream stderr = process.getErrorStream ();
    final InputStream stdout = process.getInputStream ();


    final ByteArrayOutputStream bos = new ByteArrayOutputStream();

    Thread errorT = new Thread() {
        public void run() {
            byte[] buf = new byte[1024];
            int len;
            try {
                while ((len = stdout.read(buf)) != -1) {
                    // process byte buffer
                    bos.write(buf, 0, len);
                    bos.flush();
                }
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    };

    errorT.start();

    Thread outputT = new Thread() {
        public void run() {
            byte[] buf = new byte[1024];
            int len;
            try {
                while ((len = stderr.read(buf)) != -1) {
                    System.err.write(buf, 0, len);
                    System.err.flush();
                }

            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

        }
    };

    outputT.start();

    stdin.write(image);
    stdin.flush();

    stdin.close();

    try {
        process.waitFor();

        errorT.join();
        outputT.join();
    } catch (InterruptedException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    }

    stdin.close();
    stderr.close();
    stdout.close();


    System.out.write(bos.toByteArray());

    return 0;
}
public int execute(列表命令行,字节[]图像)引发IOException{
ProcessBuilder ProcessBuilder=新的ProcessBuilder(命令行);
最终流程=processBuilder.start();
OutputStream stdin=process.getOutputStream();
final InputStream stderr=process.getErrorStream();
final InputStream stdout=process.getInputStream();
final ByteArrayOutputStream bos=新建ByteArrayOutputStream();
线程错误t=新线程(){
公开募捐{
字节[]buf=新字节[1024];
内伦;
试一试{
而((len=stdout.read(buf))!=-1){
//进程字节缓冲区
bos.write(buf,0,len);
bos.flush();
}
}捕获(IOE异常){
//TODO自动生成的捕捉块
e、 printStackTrace();
}
}
};
error.start();
线程输出=新线程(){
公开募捐{
字节[]buf=新字节[1024];
内伦;
试一试{
而((len=stderr.read(buf))!=-1){
系统错误写入(buf,0,len);
System.err.flush();
}
}捕获(IOE异常){
//TODO自动生成的捕捉块
e、 printStackTrace();
}
}
};
output.start();
标准写入(图像);
stdin.flush();
stdin.close();
试一试{
process.waitFor();
error.join();
output.join();
}捕捉(中断异常e1){
//TODO自动生成的捕捉块
e1.printStackTrace();
}
stdin.close();
stderr.close();
stdout.close();
System.out.write(bos.toByteArray());
返回0;
}

谢谢你的回答。我照你的建议做了,但现在我还有其他错误。我编辑了这篇文章来展示他们
errorT.join();
outputT.join();
commandLine.add("jpegoptim");
commandLine.add("-m90");
commandLine.add("--stdout");
commandLine.add("--stdin");
commandLine.add("pngquant");
commandLine.add("--quality=70-80");
commandLine.add("-");
public int execute(List<String> commandLine, byte[] image) throws IOException {

    ProcessBuilder processBuilder = new ProcessBuilder(commandLine);

    final Process process = processBuilder.start();

    OutputStream stdin = process.getOutputStream ();
    final InputStream stderr = process.getErrorStream ();
    final InputStream stdout = process.getInputStream ();


    final ByteArrayOutputStream bos = new ByteArrayOutputStream();

    Thread errorT = new Thread() {
        public void run() {
            byte[] buf = new byte[1024];
            int len;
            try {
                while ((len = stdout.read(buf)) != -1) {
                    // process byte buffer
                    bos.write(buf, 0, len);
                    bos.flush();
                }
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    };

    errorT.start();

    Thread outputT = new Thread() {
        public void run() {
            byte[] buf = new byte[1024];
            int len;
            try {
                while ((len = stderr.read(buf)) != -1) {
                    System.err.write(buf, 0, len);
                    System.err.flush();
                }

            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

        }
    };

    outputT.start();

    stdin.write(image);
    stdin.flush();

    stdin.close();

    try {
        process.waitFor();

        errorT.join();
        outputT.join();
    } catch (InterruptedException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    }

    stdin.close();
    stderr.close();
    stdout.close();


    System.out.write(bos.toByteArray());

    return 0;
}