【发布时间】:2017-05-07 01:03:29
【问题描述】:
我正在使用在 stackover flow 上发布的 code 将自定义元数据写入 PNG 图像并读取它。写函数似乎工作正常,但是当我尝试读取我写的数据时,它会抛出 NullPointerException。谁能告诉我怎么了?
这是编写元数据的代码
try{
image=ImageIO.read(new FileInputStream("input.png"));
writeCustomData(image, "software", "FRDDC");
ImageIO.write(image, "png", new File("output.png"));
}
catch(Exception e){
e.printStackTrace();
}
元数据的写入方法
public static 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
javax.imageio.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();
javax.imageio.stream.ImageOutputStream stream = ImageIO.createImageOutputStream(baos);
writer.setOutput(stream);
writer.write(metadata, new IIOImage(buffImg, null, metadata), writeParam);
try {
ImageIO.write(buffImg, "png", new File("new.png"));
} catch (Exception e) {
e.printStackTrace();
}
stream.close();
return baos.toByteArray();
}
读取元数据
try{
image=ImageIO.read(new FileInputStream("output.png"));
ByteArrayOutputStream baos=new ByteArrayOutputStream();
ImageIO.write(image, "png", baos );
byte[] b=baos.toByteArray();
String out=readCustomData(b, "software");
}
catch(Exception e){
e.printStackTrace();
}
读取元数据的方法
public static 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
javax.imageio.metadata.IIOMetadata metadata = imageReader.getImageMetadata(0);
//this cast helps getting the contents
//Node n=metadata.getAsTree("javax_imageio_png_1.0");
//NodeList childNodes=n.getChildNodes();
PNGMetadata pngmeta = (PNGMetadata) metadata;
if(pngmeta.getStandardTextNode()==null){
System.out.println("not found");
}
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;
}
错误信息
not found
java.lang.NullPointerException
at PNGMeta.readCustomData(PNGMeta.java:104)
at PNGMeta.main(PNGMeta.java:40)
BUILD SUCCESSFUL (total time: 2 seconds)
【问题讨论】:
-
看到错误消息会很有趣。 PNG实际上是否包含元数据“名称”?否则 readCustomData() 返回一个 null,这可能是一个提示,因为您提到了 NullPointerException
-
请编辑您的问题并包含您看到的异常的完整堆栈跟踪。
-
@VGR 我添加了堆栈跟踪
-
@FlorianHeer PNG 不包含字段“名称”。我正在尝试自己添加它
-
根据您的代码,这是您尝试读取而不是写入的字段。
标签: java png metadata javax.imageio