-1

I am working on a Spring based application in which we would like to use ImageMagick for some image processing. We have some commands, which I want to try out after text-processing(mainly splitting the string at specific length), and then calling ImageMagick commands. Unfortunately, whenever I run the Process class, I get strange errors, but when I copy paste the exact command in my terminal, it works good.

Example code :

 public @ResponseBody void setText(){
        String text = "Lorem ipsum <NAME> dolor sit amet, consectetuer adipiscing elit." +
                " Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus " +
                "et magnis dis <NAME> parturient montes, nascetur ridiculus mus. " +
                "Donec quam felis, ultricies nec, pellentesque eu, pretium quis";
        String processedText = "";
        if(text.length()>20){
            for (int i = 0; i < text.length(); i += 20) {
                //processedText += "\n";
                processedText += text.substring(i, Math.min(i + 20, text.length()));
            }
        }
        try {
            String path = "convert /home/akshay/output.png -font /home/akshay/cabin.ttf -gravity west -pointsize 13 " +
                    "-annotate +50+300 \n'"+processedText+"' /home/akshay/output.jpg";
            System.out.println("path is "+path);

            Process proc = Runtime.getRuntime().exec(path);

                BufferedReader stdInput = new BufferedReader(new
                        InputStreamReader(proc.getInputStream()));

                BufferedReader stdError = new BufferedReader(new
                        InputStreamReader(proc.getErrorStream()));

                System.out.println("Here is the standard output of the command:\n");
                String s = null;
                while ((s = stdInput.readLine()) != null) {
                    System.out.println(s);
                }

                System.out.println("Here is the standard error of the command (if any):\n");
                while ((s = stdError.readLine()) != null) {
                    System.out.println(s);
                }

        }catch (Exception e){
            e.printStackTrace();
        }
    }

Error log :

path is convert /home/akshay/output.png -font /home/akshay/cabin.ttf -gravity west -pointsize 13 -annotate +50+300 
'Lorem ipsum <NAME> dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis <NAME> parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis' /home/akshay/output.jpg
Here is the standard output of the command:

Here is the standard error of the command (if any):

convert: unable to open image `ipsum': No such file or directory @ error/blob.c/OpenBlob/2712.
convert: no decode delegate for this image format `' @ error/constitute.c/ReadImage/501.
convert: unable to open image `<NAME>': No such file or directory @ error/blob.c/OpenBlob/2712.
convert: no decode delegate for this image format `' @ error/constitute.c/ReadImage/501.
convert: unable to open image `dolor': No such file or directory @ error/blob.c/OpenBlob/2712.
convert: no decode delegate for this image format `' @ error/constitute.c/ReadImage/501.
convert: unable to open image `sit': No such file or directory @ error/blob.c/OpenBlob/2712.
convert: no decode delegate for this image format `' @ error/constitute.c/ReadImage/501.
convert: unable to open image `amet,': No such file or directory @ error/blob.c/OpenBlob/2712.
convert: no decode delegate for this image format `' @ error/constitute.c/ReadImage/501.
convert: unable to open image `consectetuer': No such file or directory @ error/blob.c/OpenBlob/2712.
convert: no decode delegate for this image format `' @ error/constitute.c/ReadImage/501.
convert: unable to open image `adipiscing': No such file or directory @ error/blob.c/OpenBlob/2712.
convert: no decode delegate for this image format `' @ error/constitute.c/ReadImage/501.

We experience this problem many times, standard commands often work weirdly, but I can't seem to find a solution for this one.

Updated command :

ProcessBuilder pb = new ProcessBuilder("convert", "/home/akshay/output.png", 
                "-gravity west","-pointsize 13","-annotate +50+300","'"+processedText+"'","/home/akshay/output.jpg");

Error log :

Here is the standard output of the command:

Here is the standard error of the command (if any):

convert: unrecognized option `-gravity west' @ error/convert.c/ConvertImageCommand/1722.

2nd variation tried

   Process proc = Runtime.getRuntime().exec(new String[]{"convert", "/home/akshay/output.png", "-font /home/akshay/cabin.ttf",
                    "-gravity west","-pointsize 13","-annotate +50+300","'"+processedText+"'","/home/akshay/output.jpg"});

Error log :

Here is the standard output of the command:

Here is the standard error of the command (if any):

convert: unrecognized option `-font /home/akshay/cabin.ttf' @ error/convert.c/ConvertImageCommand/1643.
James Z
  • 12,209
  • 10
  • 24
  • 44
We are Borg
  • 5,117
  • 17
  • 102
  • 225
  • 2
    Why `\n` in the middle of a command line? What was your intent? – Jean-Baptiste Yunès Aug 24 '18 at 11:50
  • I would first try to use [`exec(String[] cmdarray)`](https://docs.oracle.com/javase/8/docs/api/java/lang/Runtime.html#exec-java.lang.String:A-) instead. Don't try to create the full path yourself. – AxelH Aug 24 '18 at 11:50
  • @Jean-BaptisteYunès : Give line breaks in the image, later I want to calculate based upon the image by multiplying height X width of available text-box, how many characters I can fit. the \n is later commented out. Thank you – We are Borg Aug 24 '18 at 11:51
  • @AxelH : I just have a single command to run. What do you mean? Can you please elaborate. Thanks – We are Borg Aug 24 '18 at 11:52
  • This duplicate will show that this is safer to use an array with the command and each parameters instead of one string. – AxelH Aug 24 '18 at 11:56
  • If you want more help, please provide an [mcve] with a command that we could reproduce but that show the same problems. I would guess the same texte but with a `echo "..." > hellowolrd.txt` – AxelH Aug 24 '18 at 12:03
  • @AxelH : I tried using ProcessBuilder, but I start getting error as unrecognized options. I have updated the main post. Kindly have a look. Thank you. – We are Borg Aug 24 '18 at 12:05
  • @AxelH : The example is minified. You would just need an image and if ur on linux system imagemagick to execute the command. I am not having an issue with simpler commands, there are many examples demonstrating that, here I am having a problem with single quote being completely ignored inside a complex command. Thank you. – We are Borg Aug 24 '18 at 12:14
  • You should reduce things to a [Minimal, Complete, and Verifiable example](http://stackoverflow.com/help/mcve). Possible duplicate of [Java Programming: call an exe from Java and passing parameters](https://stackoverflow.com/q/5604698/608639), [Execute external program in java](https://stackoverflow.com/q/13991007/608639), [Execute external program from Java](https://stackoverflow.com/q/2875085/608639), etc. – jww Aug 24 '18 at 12:43

2 Answers2

2

The point of the exec with array is that every command, parameter, value are in a different String, this is. The point is that you don't have to bother about the possible space in a parameter (like in you text). so :

Process proc = new ProcessBuilder(
                "convert", 
                "test.png", 
                "-gravity", "west", 
                "-pointsize","13", 
                "-annotate", "+50+300", 
                processedText, 
                "test.png").start();

Note that you don't need to add any '

And you are good to go.

AxelH
  • 14,325
  • 2
  • 25
  • 55
0

The String[] passed in to the exec method needs to have everything split up. Every string is treated as a single option to the command. So for instance "-gravity west" is passed as a whole to the command, which is then unable to interpret that. Instead use "-gravity", "west" split up. So split on every space.

Hiery Nomus
  • 17,429
  • 2
  • 41
  • 37