0

I am using jhead to check if an image has an Orientation flag set, and if it is, then rotate it and set the exif information to indicate it does not need to be rotated when viewed. On the commandline it looks like:

jhead -autorot 'IMG_3680.JPG'

I am trying to use ProcessBuilder to call this from my java app on the images I am looking at, but it uses jpegtran to do the actual image rotation. Both these apps work correctly from the commandline and are located in /opt/local/bin on my mac.

I keep getting:

sh: jpegtran: command not found

Error : Problem executing specified command
in file '/images/IMG_3681.JPG'

My code is:

public static void main(String[] args) throws Exception {

    File[] files = (new File("/images")).listFiles();
    for (File file : files){
      ProcessBuilder pb = new ProcessBuilder("jhead", "-autorot", file.getAbsolutePath());
      pb.redirectOutput(Redirect.INHERIT);
      pb.redirectError(Redirect.INHERIT);
      Process p = pb.start();
    }
}

Do I need to provide a hint to ProcessBuilder in order for jhead to be able to call jpegtran?

Jacob Schoen
  • 14,034
  • 15
  • 82
  • 102
  • jhead -autorot 'IMG_3680.JPG' : does this work in your command line without any errors ? – Shamis Shukoor Dec 04 '12 at 05:35
  • Path you tried passing the full command to process builder? `/opt/local/bin/jhead` – MadProgrammer Dec 04 '12 at 05:37
  • @sheldonCooper Yes that does work on the commandline – Jacob Schoen Dec 04 '12 at 05:40
  • @MadProgrammer Passing the full command yields the same result. – Jacob Schoen Dec 04 '12 at 05:41
  • just a try - Can you use System.Runtime to execute the command ? – Shamis Shukoor Dec 04 '12 at 05:43
  • It is possible that the path to `/images` is invalid. I assume that it's in the root directory of you drive? You may want to set the `ProcessBuilder` working directory to match it. See [`ProcessBuilder#directory(File)`](http://docs.oracle.com/javase/7/docs/api/java/lang/ProcessBuilder.html) – MadProgrammer Dec 04 '12 at 05:44
  • @sheldonCooper Using `Runtime` doesn't seem to work, though I don't see an easy way to redirect the output to verify. But I know my test images are not changed. – Jacob Schoen Dec 04 '12 at 05:50
  • @MadProgrammer Setting the directory did not help either. The path exists, and is correct, as I loop through the contents, so if it was incorrect, at best the array would be null causing an exception when the loop occurs. And I should add that it is finding all the files, as I am printing out some other info in my code like the MD5Sum to see if it has changed. – Jacob Schoen Dec 04 '12 at 05:52
  • I am tempted to fire up a linux vm to see if it works there, as I had to install jhead and jpegtran on my mac and from what I understand they are fairly common on Linux. So may it is OS X weirdness or I messed something up. – Jacob Schoen Dec 04 '12 at 05:55
  • @jschoen Does the directory exists on the root directory of you execution volume? `new File("/Images").getAbsolutePath()` will return `/Images` – MadProgrammer Dec 04 '12 at 06:20
  • @MadProgrammer Thanks for the help I got it figured out. You can see my answer below. – Jacob Schoen Dec 04 '12 at 06:32

1 Answers1

0

After some guess work, I determined that the PATH environment variable was not set correctly. It had /usr/bin:/bin:/usr/sbin which obviously does not include /opt/local/bin. I added it like so:

Map<String, String> env = pb.environment();
env.put("PATH", env.get("PATH")+":/opt/local/bin/");

Which now produces the correct result. The real solution though is to add /opt/local/bin/ to the PATH environment variable and not add this in the code directly.


UPDATE: After some more looking it seems this would not have been a problem if I ran my app from Terminal instead of Eclipse. The PATH variable is set correctly in Terminal, but I had to add it to Eclipse. To add it to Eclipse:
  1. Goto Run -> Run Configurations -> Environment
  2. Click new and for the Name enter PATH and Value enter /usr/bin:/bin:/usr/sbin:/sbin:/opt/local/bin/
  3. Click Apply.

If you do need to set this in OS X then there seems to be a few ways (or really a few places). If you need it for applications that are launched via Spotlight then go here. If you need to set if for Terminal than go here.

Community
  • 1
  • 1
Jacob Schoen
  • 14,034
  • 15
  • 82
  • 102
  • because when you run from Terminal, your program inherits the environment of terminal, same with eclipse – acheron55 Apr 24 '14 at 17:47