Add TIF decoder update metadata parser

That's Twelvemonkeys for TIF
Drewnoakes for metadata
This commit is contained in:
Knut Forkalsrud 2023-10-16 18:50:44 -07:00
parent d98455658b
commit cb2a20ed2c
4 changed files with 51 additions and 27 deletions

19
pom.xml
View file

@ -119,7 +119,7 @@
<dependency> <dependency>
<groupId>com.drewnoakes</groupId> <groupId>com.drewnoakes</groupId>
<artifactId>metadata-extractor</artifactId> <artifactId>metadata-extractor</artifactId>
<version>2.6.2</version> <version>2.18.0</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>javax.servlet</groupId> <groupId>javax.servlet</groupId>
@ -220,6 +220,23 @@
<artifactId>tika-core</artifactId> <artifactId>tika-core</artifactId>
<version>2.9.0</version> <version>2.9.0</version>
</dependency> </dependency>
<dependency>
<groupId>com.twelvemonkeys.imageio</groupId>
<artifactId>imageio-jpeg</artifactId>
<version>3.9.4</version>
</dependency>
<dependency>
<groupId>com.twelvemonkeys.imageio</groupId>
<artifactId>imageio-tiff</artifactId>
<version>3.9.4</version>
</dependency>
<dependency>
<groupId>com.twelvemonkeys.servlet</groupId>
<artifactId>servlet</artifactId>
<version>3.9.4</version>
</dependency>
<dependency> <dependency>
<groupId>org.eclipse.jetty</groupId> <groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId> <artifactId>jetty-server</artifactId>

View file

@ -17,6 +17,8 @@ import javax.imageio.ImageReadParam;
import javax.imageio.ImageReader; import javax.imageio.ImageReader;
import javax.imageio.stream.ImageInputStream; import javax.imageio.stream.ImageInputStream;
import com.drew.imaging.ImageMetadataReader;
import com.drew.imaging.ImageProcessingException;
import com.drew.imaging.jpeg.JpegProcessingException; import com.drew.imaging.jpeg.JpegProcessingException;
import org.forkalsrud.album.db.DirectoryProps; import org.forkalsrud.album.db.DirectoryProps;
import org.forkalsrud.album.video.MovieCoder; import org.forkalsrud.album.video.MovieCoder;
@ -83,7 +85,7 @@ public class DirectoryMetadataGenerator {
// cache.properties and album.properties // cache.properties and album.properties
continue; continue;
} }
if (name.endsWith(".jpg") || name.endsWith(".jpeg") || name.endsWith(".JPG")) { if (name.endsWith(".jpg") || name.endsWith(".jpeg") || name.endsWith(".JPG") || name.endsWith(".tif") || name.endsWith(".tiff") || name.endsWith(".TIF")) {
Map<String, String> p = generateThumbnailProperties(f); Map<String, String> p = generateThumbnailProperties(f);
if (p != null) { if (p != null) {
addPropsForFile(props, f, p); addPropsForFile(props, f, p);
@ -132,21 +134,26 @@ public class DirectoryMetadataGenerator {
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd-HHmmss"); SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd-HHmmss");
NumberFormat nf = new DecimalFormat("0"); NumberFormat nf = new DecimalFormat("0");
Metadata metadata; Metadata metadata;
try { try {
metadata = JpegMetadataReader.readMetadata(f); metadata = ImageMetadataReader.readMetadata(f);
} catch (JpegProcessingException e) { } catch (ImageProcessingException e) {
// not a JPEG file // not a JPEG file
return null; return null;
} }
try { try {
Directory exifDirectory = metadata.getDirectory(ExifIFD0Directory.class); Directory exifDirectory = metadata.getFirstDirectoryOfType(ExifIFD0Directory.class);
if (exifDirectory != null && exifDirectory.containsTag(ExifIFD0Directory.TAG_ORIENTATION)) { if (exifDirectory != null
int orientation = exifDirectory.getInt(ExifIFD0Directory.TAG_ORIENTATION); && exifDirectory.containsTag(ExifSubIFDDirectory.TAG_IMAGE_WIDTH)
props.put("orientation", nf.format(orientation)); && exifDirectory.containsTag(ExifSubIFDDirectory.TAG_IMAGE_HEIGHT)) {
hasOrientation = true; int width = exifDirectory.getInt(ExifSubIFDDirectory.TAG_IMAGE_WIDTH);
int height = exifDirectory.getInt(ExifSubIFDDirectory.TAG_IMAGE_HEIGHT);
props.put("dimensions", new Dimension(width, height).toString());
hasDim = true;
} }
Directory exifSubDirectory = metadata.getDirectory(ExifSubIFDDirectory.class);
Directory exifSubDirectory = metadata.getFirstDirectoryOfType(ExifSubIFDDirectory.class);
if (exifSubDirectory != null && exifSubDirectory.containsTag(ExifSubIFDDirectory.TAG_EXIF_IMAGE_WIDTH) && if (exifSubDirectory != null && exifSubDirectory.containsTag(ExifSubIFDDirectory.TAG_EXIF_IMAGE_WIDTH) &&
exifSubDirectory.containsTag(ExifSubIFDDirectory.TAG_EXIF_IMAGE_HEIGHT)) { exifSubDirectory.containsTag(ExifSubIFDDirectory.TAG_EXIF_IMAGE_HEIGHT)) {
int width = exifSubDirectory.getInt(ExifSubIFDDirectory.TAG_EXIF_IMAGE_WIDTH); int width = exifSubDirectory.getInt(ExifSubIFDDirectory.TAG_EXIF_IMAGE_WIDTH);
@ -165,11 +172,13 @@ public class DirectoryMetadataGenerator {
String comment = exifSubDirectory.getString(ExifSubIFDDirectory.TAG_USER_COMMENT); String comment = exifSubDirectory.getString(ExifSubIFDDirectory.TAG_USER_COMMENT);
props.put("comment", comment); props.put("comment", comment);
} }
Directory jpegDirectory = metadata.getDirectory(JpegDirectory.class);
if (jpegDirectory.containsTag(JpegDirectory.TAG_JPEG_IMAGE_WIDTH) && JpegDirectory jpegDirectory = metadata.getFirstDirectoryOfType(JpegDirectory.class);
jpegDirectory.containsTag(JpegDirectory.TAG_JPEG_IMAGE_HEIGHT)) { if (jpegDirectory != null
int width = jpegDirectory.getInt(JpegDirectory.TAG_JPEG_IMAGE_WIDTH); && jpegDirectory.containsTag(JpegDirectory.TAG_IMAGE_WIDTH)
int height = jpegDirectory.getInt(JpegDirectory.TAG_JPEG_IMAGE_HEIGHT); && jpegDirectory.containsTag(JpegDirectory.TAG_IMAGE_HEIGHT)) {
int width = jpegDirectory.getImageWidth();
int height = jpegDirectory.getImageHeight();
props.put("dimensions", new Dimension(width, height).toString()); props.put("dimensions", new Dimension(width, height).toString());
hasDim = true; hasDim = true;
} }
@ -196,7 +205,7 @@ public class DirectoryMetadataGenerator {
private Date getExifDate(Directory exifDirectory, int tagName) throws MetadataException { private Date getExifDate(Directory exifDirectory, int tagName) throws MetadataException {
String dateStr = (String)exifDirectory.getObject(tagName); String dateStr = exifDirectory.getString(tagName);
if (" : : : : ".equals(dateStr)) { if (" : : : : ".equals(dateStr)) {
return null; return null;
} }

View file

@ -274,7 +274,12 @@ public class AlbumServlet
if (pathInfo.endsWith(".json")) { if (pathInfo.endsWith(".json")) {
pathInfo = pathInfo.substring(0, pathInfo.length() - ".json".length()); pathInfo = pathInfo.substring(0, pathInfo.length() - ".json".length());
handleJson(req, res, (DirectoryEntry)resolveEntry(pathInfo)); DirectoryEntry directoryEntry = (DirectoryEntry)resolveEntry(pathInfo);
if (directoryEntry == null) {
res.setStatus(HttpServletResponse.SC_NOT_FOUND);
return;
}
handleJson(req, res, directoryEntry);
return; return;
} }
@ -298,7 +303,6 @@ public class AlbumServlet
return; return;
} }
} catch (Exception e) { } catch (Exception e) {
e.fillInStackTrace();
throw new ServletException("sadness", e); throw new ServletException("sadness", e);
} }
res.setStatus(HttpServletResponse.SC_NOT_FOUND); res.setStatus(HttpServletResponse.SC_NOT_FOUND);

View file

@ -171,13 +171,7 @@ public class PictureScaler {
intermediate = intermediate.doubled(); intermediate = intermediate.doubled();
} }
Iterator<ImageReader> readers = ImageIO.getImageReadersByFormatName("jpg"); BufferedImage img = ImageIO.read(file);
ImageReader reader = readers.next();
ImageInputStream iis = ImageIO.createImageInputStream(file);
reader.setInput(iis, true);
ImageReadParam param = reader.getDefaultReadParam();
BufferedImage img = reader.read(0, param);
iis.close();
// The orientation is about flipping and rotating. Here is what an 'F' looks like // The orientation is about flipping and rotating. Here is what an 'F' looks like
// on pictures with each orientation. // on pictures with each orientation.