Setting Tiff tags when saving a Tiff file in Java is tricky. PDFBox does this, putting some basic tags on the exported file 1, but it does not give you the option to change or add tags.

To achieve the same results as the following codes, you need some Java objects:

With these in your hands, create an IIOMetadata object.

1
2
3
4
5
6
7
IIOMetadata metadata = writer.getDefaultImageMetadata(new ImageTypeSpecifier(bim), param);
String metaDataFormat = metadata.getNativeMetadataFormatName();
IIOMetadataNode root = new IIOMetadataNode(metaDataFormat);
IIOMetadataNode ifd = new IIOMetadataNode("TIFFIFD");
root.appendChild(ifd);
ifd.appendChild(createAsciiField(305, "Software", "MyApp"));
metadata.mergeTree(metaDataFormat, root);

The sixth line is where one specific tag is being created. It uses createAsciiField(), one of the methods from PDFBox’s TIFFUtil class.

private static IIOMetadataNode createShortField(int tiffTagNumber, String name, int val) {
    IIOMetadataNode field = new IIOMetadataNode("TIFFField");
    field.setAttribute("number", Integer.toString(tiffTagNumber));
    field.setAttribute("name", name);
    IIOMetadataNode arrayNode = new IIOMetadataNode("TIFFShorts");
    field.appendChild(arrayNode);
    IIOMetadataNode valueNode = new IIOMetadataNode("TIFFShort");
    arrayNode.appendChild(valueNode);
    valueNode.setAttribute("value", Integer.toString(val));
    return field;
}

private static IIOMetadataNode createAsciiField(int number, String name, String val) {
    IIOMetadataNode field = new IIOMetadataNode("TIFFField");
    field.setAttribute("number", Integer.toString(number));
    field.setAttribute("name", name);
    IIOMetadataNode arrayNode = new IIOMetadataNode("TIFFAsciis");
    field.appendChild(arrayNode);
    IIOMetadataNode valueNode = new IIOMetadataNode("TIFFAscii");
    arrayNode.appendChild(valueNode);
    valueNode.setAttribute("value", val);
    return field;
}

private static IIOMetadataNode createLongField(int number, String name, long val) {
    IIOMetadataNode field = new IIOMetadataNode("TIFFField");
    field.setAttribute("number", Integer.toString(number));
    field.setAttribute("name", name);
    IIOMetadataNode arrayNode = new IIOMetadataNode("TIFFLongs");
    field.appendChild(arrayNode);
    IIOMetadataNode valueNode = new IIOMetadataNode("TIFFLong");
    arrayNode.appendChild(valueNode);
    valueNode.setAttribute("value", Long.toString(val));
    return field;
}

private static IIOMetadataNode createRationalField(int number, String name, int numerator, int denominator) {
    IIOMetadataNode field = new IIOMetadataNode("TIFFField");
    field.setAttribute("number", Integer.toString(number));
    field.setAttribute("name", name);
    IIOMetadataNode arrayNode = new IIOMetadataNode("TIFFRationals");
    field.appendChild(arrayNode);
    IIOMetadataNode valueNode = new IIOMetadataNode("TIFFRational");
    arrayNode.appendChild(valueNode);
    valueNode.setAttribute("value", numerator + "/" + denominator);
    return field;
}

There is one method for each Tiff tag type.

Let’s take the DocumentName Tiff tag as an example. Suppose you want to add this tag to your Tiff file. As you can see on https://www.awaresystems.be/imaging/tiff/tifftags/documentname.html it has:

  • Type: ASCII
    • So you need to use the createAsciiField() method
  • Code: 269
    • This is the first createAsciiField() parameter
  • Name: DocumentName
    • This is the second createAsciiField() parameter
  • The third createAsciiField() parameter is the value you want inside the tag. In this case, the value inside the DocumentName tag.
ifd.appendChild(createAsciiField(269, "DocumentName", "My Document Name"));

You can use the logic above for all other tags and repeat the sixth line for each tag chosen before the metadata.mergeTree(metaDataFormat, root); call.

Once the IIOMetadata metadata object is created, you can pass it as the third parameter of the IIOImage constructor, that in turn, is the first parameter of javax.imageio.ImageWriter.write() and javax.imageio.ImageWriter.writeToSequence().

In our Convert a multi-page PDF into a multi-page Tiff example, the writeToSequence() call now should be:

writer.writeToSequence(new IIOImage(bim, null, metadata), null);

Other options