LoginSignup
10
8

More than 5 years have passed since last update.

Javaで画像の解像度(dpi)を取得する

Last updated at Posted at 2016-05-14

仕事で必要に迫られて調べたのだが、日本語の情報がほとんど見つからなかったのでメモとして残しておきます。

まずは 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);
10
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
8