Question

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

I an invoking the command to the process like so: /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?

Was it helpful?

Solution

You might want to look at Apache Commons Exec this gives you a good way of running executables and passing the results into 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.

OTHER TIPS

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

    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);
        }

    }

The Runtime.exec() method returns a Process that has methods for getting the input, output and error streams of the invoked 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.

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

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top