I’m interested in parsing multiple segments of a JPG file. Using apache-commons-imaging (that is the library I am working with – please do not suggest other libraries), this is the code I came up with (MWE):
package org.test.exiftest;
import org.apache.commons.imaging.Imaging;
import org.apache.commons.imaging.ImagingException;
import org.apache.commons.imaging.bytesource.ByteSource;
import org.apache.commons.imaging.common.ImageMetadata;
import org.apache.commons.imaging.formats.jpeg.JpegImageMetadata;
import org.apache.commons.imaging.formats.jpeg.JpegImageParser;
import org.apache.commons.imaging.formats.jpeg.segments.GenericSegment;
import org.apache.commons.imaging.formats.tiff.TiffImageMetadata;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
public class Main {
public static void main(String[] args) {
final Path src = Path.of("your_file.JPG");
parseExif(src);
parseSegments(src);
}
private static void parseExif(Path src) {
try (final InputStream is = Files.newInputStream(src)) {
ImageMetadata meta = Imaging.getMetadata(is, "testfile");
var parsedExif = ((JpegImageMetadata)(meta)).getExif();
} catch (final IOException e) {
System.out.println("Erraror: " + e.getMessage());
}
}
private static void parseSegments(Path src) {
try (final InputStream is = Files.newInputStream(src)) {
ByteSource bs = ByteSource.inputStream(is, "testfile");
JpegImageParser parser = new JpegImageParser();
var segments = parser.readSegments(bs, null, false);
for (var s : segments) {
System.out.println(s.getDescription());
}
var rawExif = ((GenericSegment)segments.getFirst()).getSegmentData();
} catch (final IOException e) {
System.out.println("Error: " + e.getMessage());
}
}
}
So I can easily get to the parsed exif data via Imaging.getMetadata()
, but this method does not return all the information about the image I want.
I would like to extract all required information from the segments themselves. However, while I can get the raw bytes for the APP1 segment (see above), I wasn’t able to find any support in the commons-imaging library to construct a TiffImageMetadata
object or something similar from those raw bytes to use the library methods to work with the exif data.
I can parse the image twice, as shown above. That works. But maybe there is a more elegant solution? Thanks.