仕事で必要に迫られて調べたのだが、日本語の情報がほとんど見つからなかったのでメモとして残しておきます。
まずは javax.imageio
のクラスを使って自前でゴリゴリ書くやり方。
GetDpiByImageReader.java
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import javax.imageio.ImageIO;
import javax.imageio.ImageReader;
import javax.imageio.metadata.IIOMetadata;
import javax.imageio.metadata.IIOMetadataFormatImpl;
import javax.imageio.metadata.IIOMetadataNode;
import javax.imageio.stream.ImageInputStream;
import java.io.File;
import java.util.Iterator;
public class GetDpiByImageReader {
public static void main(String... args) throws Exception {
String imagePath = args[0];
System.out.println(imagePath);
try (ImageInputStream iis = ImageIO.createImageInputStream(new File(imagePath))) {
Iterator<ImageReader> it = ImageIO.getImageReaders(iis);
if (!it.hasNext()) {
System.out.println("Can't get ImageReaders");
return;
}
ImageReader reader = it.next();
reader.setInput(iis);
IIOMetadata metadata = reader.getImageMetadata(0);
IIOMetadataNode rootNode = (IIOMetadataNode) metadata.getAsTree(IIOMetadataFormatImpl.standardMetadataFormatName);
int xDpi = -1;
int yDpi = -1;
// 横DPIを取得
NodeList nodes = rootNode.getElementsByTagName("HorizontalPixelSize");
if (nodes.getLength() > 0) {
IIOMetadataNode node = (IIOMetadataNode) nodes.item(0);
NamedNodeMap nodeAttrs = node.getAttributes();
Node attr = nodeAttrs.item(0);
xDpi = Math.round(25.4f / Float.parseFloat(attr.getNodeValue()));
}
// 縦DPIを取得
nodes = rootNode.getElementsByTagName("VerticalPixelSize");
if (nodes.getLength() > 0) {
IIOMetadataNode node = (IIOMetadataNode) nodes.item(0);
NamedNodeMap nodeAttrs = node.getAttributes();
Node attr = nodeAttrs.item(0);
yDpi = Math.round(25.4f / Float.parseFloat(attr.getNodeValue()));
}
System.out.println(String.format("横 %d DPI", xDpi));
System.out.println(String.format("縦 %d DPI", yDpi));
}
}
}
Commons Imagingにズバリdpiを返すメソッドがあるので実際はそれを使えば良いでしょう。
GetDpiByCommonsImaging.java
import org.apache.commons.imaging.ImageInfo;
import org.apache.commons.imaging.Imaging;
import java.io.File;
public class GetDpiByCommonsImaging {
public static void main(String... args) throws Exception {
ImageInfo info = Imaging.getImageInfo(new File(args[0]));
System.out.println(String.format("横 %d DPI", info.getPhysicalWidthDpi()));
System.out.println(String.format("縦 %d DPI", info.getPhysicalHeightDpi()));
}
}
ImageInfoには、getPhysicalHeightInch()
というようなDPIとピクセル数から求めたインチを返してくれるメソッドもあるのだが、ミリを返すメソッドはないので自前で計算する。
double h = Math.round(info.getPhysicalHeightInch() * 25.4);
double w = Math.round(info.getPhysicalWidthInch() * 25.4);