你会如何从像Image Magick In Java这样的程序中读取图像数据?

时间:2022-12-24 17:28:24

I am working with ImageMagick and am wondering what the best way to read image data in from StdOut of the ImageMagick process.

我正在使用ImageMagick,我想知道从ImageMagick进程的StdOut中读取图像数据的最佳方法是什么。

I an invoking the command to the process like so: /opt/local/bin/convert -resize 8000@ - -

我像这样调用该过程的命令:/ opt / local / bin / convert -resize 8000 @ - -

and then piping a byte array to the process for processing.

然后将一个字节数组传递给进程进行处理。

what is the best way to read data from a process like this?

从这样的进程读取数据的最佳方法是什么?

4 个解决方案

#1


You might want to look at Apache Commons Exec this gives you a good way of running executables and passing the results into Java.

您可能希望查看Apache Commons Exec,这为您提供了一种运行可执行文件并将结果传递给Java的好方法。

It's similar to using the method Michael mentioned except should allow you more control.

它与使用迈克尔提到的方法类似,但应该允许您更多控制。

There are some good examples of usage on the tutorial page.

在教程页面上有一些很好的使用示例。

#2


Just want to post a code sample using ImageMagick via Apache commons exec for completeness

只想通过Apache commons exec使用ImageMagick发布代码示例以保证完整性

    try {

        StringBuffer sb = new StringBuffer();
        sb.append(this.validPathToImageMagickCommand);
        sb.append('\u0020');
        for (int i = 0; i < args.size(); i++) {
            String s = args.get(i);
            sb.append(s);
        }


        CommandLine cl = CommandLine.parse(sb.toString());

        PumpStreamHandler pumpStreamHandler = new PumpStreamHandler(output, System.err, new ByteArrayInputStream(inputBytes));
        byAs = new ByteArrayInputStream(inputBytes);
        pumpStreamHandler.setProcessOutputStream(byAs);

        DefaultExecutor executor = new DefaultExecutor();
        executor.setStreamHandler(pumpStreamHandler);
        int exitValue = executor.execute(cl);

        outputBytes = output.toByteArray();
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        try {
            if (byAs != null)
                byAs.close();

            if (output != null)
                output.close();

        } catch (IOException e) {
            System.out.println(e);
        }

    }

#3


The Runtime.exec() method returns a Process that has methods for getting the input, output and error streams of the invoked process.

Runtime.exec()方法返回一个Process,该Process具有获取调用进程的输入,输出和错误流的方法。

I do wonder how you managed to "pipe a byte array to the process" in any other way.

我想知道你是如何设法“以任何其他方式将字节数组传递给进程”。

Note that you'll have to use multiple threads to handle the input and the output of the spawned process because it will block if you try to "pipe in" a lot of input without reading any output.

请注意,您必须使用多个线程来处理生成进程的输入和输出,因为如果您尝试“输入”大量输入而不读取任何输出,它将会阻塞。

#4


If you do want to use Runtime.exec(), please review this question as runtime.exec() can be a bit tricky.

如果您确实想使用Runtime.exec(),请查看此问题,因为runtime.exec()可能有点棘手。

You will be wanting to change the StreamGobbler for OUTPUT into something that stores stdout in an array or some such. And start the threads before doing waitFor() to prevent, as Michael said, blocking.

您将希望将OUTPUT的StreamGobbler更改为将stdout存储在数组中的某些内容。并且在执行waitFor()之前启动线程,以防止,正如迈克尔所说,阻止。

#1


You might want to look at Apache Commons Exec this gives you a good way of running executables and passing the results into Java.

您可能希望查看Apache Commons Exec,这为您提供了一种运行可执行文件并将结果传递给Java的好方法。

It's similar to using the method Michael mentioned except should allow you more control.

它与使用迈克尔提到的方法类似,但应该允许您更多控制。

There are some good examples of usage on the tutorial page.

在教程页面上有一些很好的使用示例。

#2


Just want to post a code sample using ImageMagick via Apache commons exec for completeness

只想通过Apache commons exec使用ImageMagick发布代码示例以保证完整性

    try {

        StringBuffer sb = new StringBuffer();
        sb.append(this.validPathToImageMagickCommand);
        sb.append('\u0020');
        for (int i = 0; i < args.size(); i++) {
            String s = args.get(i);
            sb.append(s);
        }


        CommandLine cl = CommandLine.parse(sb.toString());

        PumpStreamHandler pumpStreamHandler = new PumpStreamHandler(output, System.err, new ByteArrayInputStream(inputBytes));
        byAs = new ByteArrayInputStream(inputBytes);
        pumpStreamHandler.setProcessOutputStream(byAs);

        DefaultExecutor executor = new DefaultExecutor();
        executor.setStreamHandler(pumpStreamHandler);
        int exitValue = executor.execute(cl);

        outputBytes = output.toByteArray();
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        try {
            if (byAs != null)
                byAs.close();

            if (output != null)
                output.close();

        } catch (IOException e) {
            System.out.println(e);
        }

    }

#3


The Runtime.exec() method returns a Process that has methods for getting the input, output and error streams of the invoked process.

Runtime.exec()方法返回一个Process,该Process具有获取调用进程的输入,输出和错误流的方法。

I do wonder how you managed to "pipe a byte array to the process" in any other way.

我想知道你是如何设法“以任何其他方式将字节数组传递给进程”。

Note that you'll have to use multiple threads to handle the input and the output of the spawned process because it will block if you try to "pipe in" a lot of input without reading any output.

请注意,您必须使用多个线程来处理生成进程的输入和输出,因为如果您尝试“输入”大量输入而不读取任何输出,它将会阻塞。

#4


If you do want to use Runtime.exec(), please review this question as runtime.exec() can be a bit tricky.

如果您确实想使用Runtime.exec(),请查看此问题,因为runtime.exec()可能有点棘手。

You will be wanting to change the StreamGobbler for OUTPUT into something that stores stdout in an array or some such. And start the threads before doing waitFor() to prevent, as Michael said, blocking.

您将希望将OUTPUT的StreamGobbler更改为将stdout存储在数组中的某些内容。并且在执行waitFor()之前启动线程,以防止,正如迈克尔所说,阻止。