Kurt的答案说明了这一点,但我仍然花了一些时间才能运行它,因此这是保存PNG时设置DPI的代码。要找到合适的作家还有很多事情要做……
private BufferedImage gridImage; ... private void saveGridImage(File output) throws IOException { output.delete(); final String formatName = "png"; for (Iterator<ImageWriter> iw = ImageIO.getImageWritersByFormatName(formatName); iw.hasNext();) { ImageWriter writer = iw.next(); ImageWriteParam writeParam = writer.getDefaultWriteParam(); ImageTypeSpecifier typeSpecifier = ImageTypeSpecifier.createFromBufferedImageType(BufferedImage.TYPE_INT_RGB); IIOmetadata metadata = writer.getDefaultImagemetadata(typeSpecifier, writeParam); if (metadata.isReadonly() || !metadata.isStandardmetadataFormatSupported()) { continue; } setDPI(metadata); final ImageOutputStream stream = ImageIO.createImageOutputStream(output); try { writer.setOutput(stream); writer.write(metadata, new IIOImage(gridImage, null, metadata), writeParam); } finally { stream.close(); } break; } } private void setDPI(IIOmetadata metadata) throws IIOInvalidTreeException { // for PMG, it's dots per millimeter double dotsPerMilli = 1.0 * DPI / 10 / INCH_2_CM; IIOmetadataNode horiz = new IIOmetadataNode("HorizontalPixelSize"); horiz.setAttribute("value", Double.toString(dotsPerMilli)); IIOmetadataNode vert = new IIOmetadataNode("VerticalPixelSize"); vert.setAttribute("value", Double.toString(dotsPerMilli)); IIOmetadataNode dim = new IIOmetadataNode("Dimension"); dim.appendChild(horiz); dim.appendChild(vert); IIOmetadataNode root = new IIOmetadataNode("javax_imageio_1.0"); root.appendChild(dim); metadata.mergeTree("javax_imageio_1.0", root); }


