Created
May 22, 2021 08:51
-
-
Save culmat/6991fd01c4d05e5636b2f22b4c733b8b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package culmat.photo; | |
import static java.util.Arrays.asList; | |
import static java.util.Arrays.stream; | |
import java.io.BufferedReader; | |
import java.io.IOException; | |
import java.io.InputStream; | |
import java.io.InputStreamReader; | |
import java.io.OutputStream; | |
import java.nio.file.Path; | |
import java.nio.file.Paths; | |
import java.util.LinkedList; | |
import java.util.List; | |
import java.util.Map; | |
import java.util.TreeMap; | |
import java.util.function.Consumer; | |
public class ExifParser implements AutoCloseable { | |
final String EOO = "{ready77}"; | |
final List<String> args = new LinkedList<>(asList("exiftool","-q","-stay_open","True","-@","-")); | |
Process lazyProc; | |
IO lazyIO; | |
boolean closed; | |
byte[] newLine = System.getProperty("line.separator").getBytes(); | |
byte[] blank = " ".getBytes(); | |
byte[] execute = (System.getProperty("line.separator")+"-execute77"+System.getProperty("line.separator")).getBytes(); | |
class IO implements AutoCloseable{ | |
final BufferedReader err, out; | |
public IO(OutputStream in, InputStream out, InputStream err) { | |
this.in = in; | |
this.out = new BufferedReader(new InputStreamReader(out)); | |
this.err = new BufferedReader(new InputStreamReader(err)); | |
} | |
final OutputStream in; | |
@Override | |
public void close() throws Exception { | |
in.close(); | |
out.close(); | |
err.close(); | |
} | |
} | |
private IO IO() throws IOException { | |
if(lazyProc == null) { | |
lazyProc = new ProcessBuilder(args).start(); | |
lazyIO = new IO( | |
lazyProc.getOutputStream(), | |
lazyProc.getInputStream(), | |
lazyProc.getErrorStream()); | |
} | |
return lazyIO; | |
} | |
public ExifParser(String ... commonargs) { | |
if(commonargs.length > 0) { | |
// common args must be at the end of the arg list | |
args.add("-common_args"); | |
args.addAll(asList(commonargs)); | |
} | |
} | |
public Map<String, String> getTags(Path path, String ... tags) throws IOException { | |
final Map<String, String> ret = new TreeMap<>(); | |
getMeta(path, (s)-> { | |
String[] pair = s.split("\\s*:\\s*",2); | |
ret.put(pair[0], pair[1]); | |
}, stream(tags).map(s -> "-"+s).toList().toArray(new String[0])); | |
return ret; | |
} | |
@SuppressWarnings("resource") | |
public void getMeta(Path path, Consumer<String> consumer, String ... args) throws IOException { | |
if(closed) throw new IllegalStateException("parser already closed"); | |
for (String a : args) { | |
IO().in.write(a.getBytes()); | |
IO().in.write(newLine); | |
} | |
IO().in.write(path.toAbsolutePath().normalize().toString().getBytes()); | |
IO().in.write(execute); | |
IO().in.flush(); | |
String line; | |
while (!(line = IO().out.readLine()).equals(EOO) ) { | |
consumer.accept(line); | |
} | |
} | |
@SuppressWarnings("resource") | |
@Override | |
public void close() throws Exception { | |
if(lazyProc != null) { | |
IO().in.write("-stay_open\nFalse\n".getBytes()); | |
IO().in.flush(); | |
lazyIO.close(); | |
lazyProc.destroy(); | |
} | |
lazyProc = null; | |
lazyIO = null; | |
closed = true; | |
} | |
public static void main(String[] args) throws Exception { | |
Path image = Paths.get("/home/XYZ/Pictures/2015/07/2015-07-03_22-41-14_250.jpg"); | |
try (ExifParser exifTool = new ExifParser("-s")) { | |
for (int i = 0; i < 2; i++) { | |
exifTool.getMeta( | |
image, | |
System.out::println, | |
"-ShutterCount","-SerialNumber"); | |
System.out.println(exifTool.getTags( | |
image, | |
"ShutterCount","SerialNumber")); | |
} | |
exifTool.getMeta( | |
image, | |
System.out::println); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment