Created
January 28, 2019 12:57
-
-
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
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 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