Skip to content

Instantly share code, notes, and snippets.

@jochenschmich
Created January 28, 2019 12:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jochenschmich/ec663f5435bf326f28a4ae6b14321b20 to your computer and use it in GitHub Desktop.
Save jochenschmich/ec663f5435bf326f28a4ae6b14321b20 to your computer and use it in GitHub Desktop.
An ANT Task that repairs the image Metadata for embedding them in an PDF with FOP
package imagefixer;
import java.awt.image.BufferedImage;
import java.awt.image.RenderedImage;
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.util.Iterator;
import javax.imageio.IIOImage;
import javax.imageio.ImageIO;
import javax.imageio.ImageTypeSpecifier;
import javax.imageio.ImageWriteParam;
import javax.imageio.ImageWriter;
import javax.imageio.metadata.IIOMetadata;
import javax.imageio.metadata.IIOMetadataNode;
import javax.imageio.spi.IIORegistry;
import javax.imageio.stream.ImageOutputStream;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Task;
import org.w3c.dom.NodeList;
public class RepairImageMetadataTask extends Task {
private static final class PNGFilter implements FilenameFilter {
public boolean accept(File dir, String name) {
return name.toLowerCase().endsWith(FILE_EXTENSION);
}
}
private static final double DIVISOR = 0.0254;
private static final String FILE_EXTENSION = "png";
private static final String PHYS_NODE = "pHYs";
private static final String PIXELS_PER_UNIT_X_AXIS = "pixelsPerUnitXAxis";
private static final String PIXELS_PER_UNIT_Y_AXIS = "pixelsPerUnitYAxis";
private static final String TASK_NAME = "repairImageMetadata";
private static final String UNIT_SPECIFIER = "unitSpecifier";
private static final String UNIT_SPECIFIER_DEFAULT = "meter";
private String folder;
private int resolution = 72;
private boolean verbose;
@Override
public void execute() throws BuildException {
IIORegistry.getDefaultInstance().registerApplicationClasspathSpis();
File file = new File(getFolder());
if (file.exists()) {
if (isVerbose()) {
log("Found Folder : " + file.getAbsolutePath());
}
File[] list = file.listFiles(new PNGFilter());
for (File child : list) {
try {
BufferedImage readImage = ImageIO.read(child);
if (readImage != null) {
if (isVerbose()) {
log("Processing Image: " + child.getAbsolutePath());
}
String name = child.getAbsolutePath();
writeFile(readImage, name, getResolution());
}
} catch (IOException exception) {
log(exception, 1);
}
}
}
}
public String getFolder() {
return folder;
}
public int getResolution() {
return resolution;
}
@Override
public String getTaskName() {
return TASK_NAME;
}
@Override
public String getTaskType() {
return super.getTaskType();
}
public boolean isVerbose() {
return verbose;
}
public void setFolder(String folder) {
this.folder = folder;
}
public void setResolution(int resolution) {
this.resolution = resolution;
}
public void setVerbose(boolean verbose) {
this.verbose = verbose;
}
private void writeFile(RenderedImage image, String filename, int dotsPerInch) {
String dotsPerMeter = String.valueOf((int) (dotsPerInch / DIVISOR));
Iterator<ImageWriter> imageWriters = ImageIO.getImageWritersByFormatName(FILE_EXTENSION);
while (imageWriters.hasNext()) {
ImageWriter imageWriter = imageWriters.next();
ImageTypeSpecifier imageType = new ImageTypeSpecifier(image);
ImageWriteParam writeParam = imageWriter.getDefaultWriteParam();
IIOMetadata metadata = imageWriter.getDefaultImageMetadata(imageType, writeParam);
String pngFormatName = metadata.getNativeMetadataFormatName();
IIOMetadataNode pngNode = (IIOMetadataNode) metadata.getAsTree(pngFormatName);
IIOMetadataNode physNode = null;
NodeList childNodes = pngNode.getElementsByTagName(PHYS_NODE);
if (childNodes.getLength() == 0) {
physNode = new IIOMetadataNode(PHYS_NODE);
pngNode.appendChild(physNode);
} else if (childNodes.getLength() == 1) {
physNode = (IIOMetadataNode) childNodes.item(0);
} else {
throw new IllegalStateException("Don't know what to do with multiple pHYs nodes");
}
physNode.setAttribute(PIXELS_PER_UNIT_X_AXIS, dotsPerMeter);
physNode.setAttribute(PIXELS_PER_UNIT_Y_AXIS, dotsPerMeter);
physNode.setAttribute(UNIT_SPECIFIER, UNIT_SPECIFIER_DEFAULT);
try {
metadata.setFromTree(pngFormatName, pngNode);
IIOImage iioImage = new IIOImage(image, null, metadata);
File file = new File(filename);
ImageOutputStream stream = ImageIO.createImageOutputStream(file);
imageWriter.setOutput(stream);
imageWriter.write(iioImage);
stream.flush();
stream.close();
} catch (Exception exception) {
log(exception, 1);
continue;
}
break;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment