如何在图像中设置DPI信息?设置 TIFF DPI

2022-09-01 10:52:02

我有一个应用程序,我想导出高分辨率(或者更确切地说,高像素密度?)图像进行打印 - 例如,我希望图像以每英寸250点(DPI)打印,而不是默认值,我理解为72 DPI。

我使用带有Graphics2D对象的BufferedImage来绘制图像,然后使用ImageIO.write()来保存图像。

任何想法,我该如何设置DPI?


答案 1

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);
 }

答案 2

设置 TIFF DPI

如果要为 TIFF 设置 dpi,请尝试通过后续步骤执行此操作:

private static IIOMetadata createMetadata(ImageWriter writer, ImageWriteParam writerParams, int resolution) throws
                                                                                                            IIOInvalidTreeException
{
    // Get default metadata from writer
    ImageTypeSpecifier type = ImageTypeSpecifier.createFromBufferedImageType(BufferedImage.TYPE_BYTE_GRAY);
    IIOMetadata meta = writer.getDefaultImageMetadata(type, writerParams);

    // Convert default metadata to TIFF metadata
    TIFFDirectory dir = TIFFDirectory.createFromMetadata(meta);

    // Get {X,Y} resolution tags
    BaselineTIFFTagSet base = BaselineTIFFTagSet.getInstance();
    TIFFTag tagXRes = base.getTag(BaselineTIFFTagSet.TAG_X_RESOLUTION);
    TIFFTag tagYRes = base.getTag(BaselineTIFFTagSet.TAG_Y_RESOLUTION);

    // Create {X,Y} resolution fields
    TIFFField fieldXRes = new TIFFField(tagXRes, TIFFTag.TIFF_RATIONAL, 1, new long[][] { { resolution, 1 } });
    TIFFField fieldYRes = new TIFFField(tagYRes, TIFFTag.TIFF_RATIONAL, 1, new long[][] { { resolution, 1 } });

    // Add {X,Y} resolution fields to TIFFDirectory
    dir.addTIFFField(fieldXRes);
    dir.addTIFFField(fieldYRes);

    // Add unit field to TIFFDirectory (change to RESOLUTION_UNIT_CENTIMETER if necessary)
    dir.addTIFFField(new TIFFField(base.getTag(BaselineTIFFTagSet.TAG_RESOLUTION_UNIT), BaselineTIFFTagSet.RESOLUTION_UNIT_INCH));

    // Return TIFF metadata so it can be picked up by the IIOImage
    return dir.getAsMetadata();
}

此外,您也可以以类似的方式设置任何TIFF标签。

源头阅读更多内容


推荐