我有一个TIFF图像已经在我的应用程序中读取并存储在BufferedImage
对象中。如何使用Java高级图像(JAI)API确定图像的水平和垂直DPI?我一直在寻找,但没有找到一个简单直接的方法来完成这个任务。
这里有一个完整的示例,使用标准的ImageIO API和标准的元数据格式提取DPI(实际上是每毫米的像素数)。复杂度,我们来了…… :-P
public class DPITest {
public static void main(String[] args) throws IOException {
File input = new File(args[0]);
ImageInputStream stream = ImageIO.createImageInputStream(input);
Iterator<ImageReader> readers = ImageIO.getImageReaders(stream);
if (readers.hasNext()) {
ImageReader reader = readers.next();
reader.setInput(stream);
IIOMetadata metadata = reader.getImageMetadata(0);
IIOMetadataNode standardTree = (IIOMetadataNode) metadata.getAsTree(IIOMetadataFormatImpl.standardMetadataFormatName);
IIOMetadataNode dimension = (IIOMetadataNode) standardTree.getElementsByTagName("Dimension").item(0);
float horizontalPixelSizeMM = getPixelSizeMM(dimension, "HorizontalPixelSize");
float verticalPixelSizeMM = getPixelSizeMM(dimension, "VerticalPixelSize");
// TODO: Convert pixelsPerMM to DPI left as an exercise to the reader.. ;-)
System.err.println("horizontalPixelSizeMM: " + horizontalPixelSizeMM);
System.err.println("verticalPixelSizeMM: " + verticalPixelSizeMM);
}
else {
System.err.printf("Could not read %s\n", input);
}
}
private static float getPixelSizeMM(final IIOMetadataNode dimension, final String elementName) {
// NOTE: The standard metadata format has defined dimension to pixels per millimeters, not DPI...
NodeList pixelSizes = dimension.getElementsByTagName(elementName);
IIOMetadataNode pixelSize = pixelSizes.getLength() > 0 ? (IIOMetadataNode) pixelSizes.item(0) : null;
return pixelSize != null ? Float.parseFloat(pixelSize.getAttribute("value")) : -1;
}
}
以下是一些阅读资料:
注意:请勿修改HTML标签。InputStream
传递给ImageIO.createImageInputStream
而不是File
,这应该适用于我正在做的事情。星期一回到办公室时会尝试这个方法。感谢您提供的信息! - MichaelInputStream
应该可以胜任。我会更新答案并提供一些指针。 - Harald Kfloat
)。double
同样可以工作。 - Harald K使用Apache Commons Sanselan工具库获取图像信息: http://commons.apache.org/imaging/index.html。
final ImageInfo imageInfo = Sanselan.getImageInfo(file);
final int physicalWidthDpi = imageInfo.getPhysicalWidthDpi();
final int physicalHeightDpi = imageInfo.getPhysicalHeightDpi();
BufferedImage
,那么你就没办法了。如果你有文件、流或类似的引用,我建议你研究一下 ImageIO API,特别是ImageReader.getImageMetadata()
,从那里获取 DPI 应该相当简单。 - Harald KImageReader
。 然后将 DPI 信息传递到我需要它的位置。 我接下来遇到的障碍似乎是当我尝试执行ImageIO.getImageReadersByFormatName("tiff")
加载读取器时,它会说找不到该类型的读取器。 仍在努力解决。 - Michael