Update PNG metadata

59 Views Asked by At

I'm trying to add information to the metadata, I wrote the following code:

ImageWriter writer = ImageIO.getImageWritersByFormatName("png").next();
ImageWriteParam writeParam = writer.getDefaultWriteParam();
ImageTypeSpecifier typeSpecifier = ImageTypeSpecifier.createFromBufferedImageType(BufferedImage.TYPE_INT_RGB);

//adding metadata
javax.imageio.metadata.IIOMetadata metadata = writer.getDefaultImageMetadata(typeSpecifier, writeParam);

IIOMetadataNode textEntry = new IIOMetadataNode("tEXtEntry");
textEntry.setAttribute("keyword", "Title");
textEntry.setAttribute("value", "1515456165165165656565165");

IIOMetadataNode text = new IIOMetadataNode("tEXt");
text.appendChild(textEntry);

IIOMetadataNode root = new IIOMetadataNode("javax_imageio_png_1.0");
root.appendChild(text);

metadata.mergeTree("javax_imageio_png_1.0", root);

BufferedImage image = ImageIO.read(tempFile);

//writing the data
IIOImage iioImage = new IIOImage(image, null, metadata);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageOutputStream stream = ImageIO.createImageOutputStream(baos);
writer.setOutput(stream);
writer.write(metadata, new IIOImage(image, null, metadata), writeParam);

File file1 = new File("C:/Users/Akiro/Desktop/Новая папка/Раб/тесты/new.png");

try {
    ImageIO.write(image, "png", file1);
} catch (Exception e) {
    e.printStackTrace();
}

stream.close();

The above code executes without errors, but no changes appear in the metadata.

What could be the error, or what is the best way to do this (preferably with an example)?

1

There are 1 best solutions below

0
Harald K On

As mentioned in the comments, the main problem with the code is that it writes the same image twice. Once to an in-memory stream, with custom metadata. And once to a file, without the custom metadata. This is the reason why the metadata appears to not change, even if you correctly update the metadata.

Instead, write only once, with metadata, to the file:

// Create custom metadata
IIOMetadataNode root = new IIOMetadataNode("javax_imageio_png_1.0");

IIOMetadataNode text = new IIOMetadataNode("tEXt");
root.appendChild(text);

IIOMetadataNode textEntry = new IIOMetadataNode("tEXtEntry");
textEntry.setAttribute("keyword", "Title");
textEntry.setAttribute("value", "your-title-here");
text.appendChild(textEntry);

// Read image data
BufferedImage image = ImageIO.read(inputFile);

// Merge with default PNG metadata
// (Note: You could also read the metadata from the inputFile and merge with that, 
// to preserve existing metadata. I'm assuming you just want to replace everything).
ImageWriter writer = ImageIO.getImageWritersByFormatName("png").next();
ImageWriteParam writeParam = writer.getDefaultWriteParam();
ImageTypeSpecifier typeSpecifier = ImageTypeSpecifier.createFromRenderedImage(image);

IIOMetadata metadata = writer.getDefaultImageMetadata(typeSpecifier, writeParam);
metadata.mergeTree("javax_imageio_png_1.0", root);

// Write image with metadata to outputFile
File outputFile = new File("new.png");

try (ImageOutputStream stream = ImageIO.createImageOutputStream(outputFile)) (
    writer.setOutput(stream);
    writer.write(null, new IIOImage(image, null, metadata), writeParam);
} catch (Exception e) {
    e.printStackTrace();
}