[ACCEPTED]-Writing image metadata in Java, preferably PNG-metadata
I had to do the the same thing some days 5 ago.. I have not found the exact solution 4 on the internet either but looking at the 3 com.sun.imageio.plugins.png.PNGMetadata
class I could achieve some results..
To 2 write a custom metadata to a PNG file:
public byte[] writeCustomData(BufferedImage buffImg, String key, String value) throws Exception {
ImageWriter writer = ImageIO.getImageWritersByFormatName("png").next();
ImageWriteParam writeParam = writer.getDefaultWriteParam();
ImageTypeSpecifier typeSpecifier = ImageTypeSpecifier.createFromBufferedImageType(BufferedImage.TYPE_INT_RGB);
//adding metadata
IIOMetadata metadata = writer.getDefaultImageMetadata(typeSpecifier, writeParam);
IIOMetadataNode textEntry = new IIOMetadataNode("tEXtEntry");
textEntry.setAttribute("keyword", key);
textEntry.setAttribute("value", value);
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);
//writing the data
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageOutputStream stream = ImageIO.createImageOutputStream(baos);
writer.setOutput(stream);
writer.write(metadata, new IIOImage(buffImg, null, metadata), writeParam);
stream.close();
return baos.toByteArray();
}
Then, to 1 read the data:
public String readCustomData(byte[] imageData, String key) throws IOException{
ImageReader imageReader = ImageIO.getImageReadersByFormatName("png").next();
imageReader.setInput(ImageIO.createImageInputStream(new ByteArrayInputStream(imageData)), true);
// read metadata of first image
IIOMetadata metadata = imageReader.getImageMetadata(0);
//this cast helps getting the contents
PNGMetadata pngmeta = (PNGMetadata) metadata;
NodeList childNodes = pngmeta.getStandardTextNode().getChildNodes();
for (int i = 0; i < childNodes.getLength(); i++) {
Node node = childNodes.item(i);
String keyword = node.getAttributes().getNamedItem("keyword").getNodeValue();
String value = node.getAttributes().getNamedItem("value").getNodeValue();
if(key.equals(keyword)){
return value;
}
}
return null;
}
Java provides the metadata
package and the ImageWriter
class 3 along with the ImageIO
package.
You create your 2 IIOMetadata
object, then getImageWriters
for your BufferedImage
or IIOImage
and use them 1 to write
the metadata.
To add to other answer, you can also try 4 the PNGJ library, it has full metadata support.
BTW, I 3 don't understand what you are refering to 2 with the "XML-like" structure 1 of metadata.
Using the method from posted by the OP gets 5 most of the way there; the only issue is 4 that PNGMetadata
is proprietary and so causes compiler 3 warnings.
There is a method of doing it without 2 using the proprietary API, by searching 1 the metadata tree for tEXtEntry
nodes:
private List<Node> findNodesWithName(String name, Node root) {
List<Node> found = new ArrayList<>();
Node n = root.getFirstChild();
while (n != null) {
if (n.getNodeName().equals(name)) {
found.add(n);
}
found.addAll(findNodesWithName(name, n));
n = n.getNextSibling();
}
}
// ...
// To use it:
IIOMetadata metadata = ...;
List<Node> tEXtNodes = findNodesWithName(
"tEXtEntry",
metadata.getAsTree(metadata.getNativeMetadataFormatName()));
for (Node n : tEXtNodes) {
String keyword = node.getAttributes().getNamedItem("keyword");
String value = node.getAttributes().getNamedItem("value");
System.out.println("keyword: " + keyword + "; value: " + value);
}
More Related questions
We use cookies to improve the performance of the site. By staying on our site, you agree to the terms of use of cookies.