如何将元数据写入png Image

时间:2014-02-17 20:47:18

标签: java image png metadata

我一直在尝试找到一种方法来将元数据写入PNG,我尝试了很多。

我可以使用pngj库读取数据:

PngReader pngr = new PngReader(file);
pngr.readSkippingAllRows(); // reads only metadata
for (PngChunk c : pngr.getChunksList().getChunks()) {
    if (!ChunkHelper.isText(c))   continue;
        PngChunkTextVar ct = (PngChunkTextVar) c;
        String key = ct.getKey();
        String val = ct.getVal();
        System.out.print(key + " " + val + "\n" );     
    }
pngr.close();

它很棒。但我需要写信给它。

我试过了:

    public boolean writeCustomData(String key, String value) throws Exception {

    PngReader pngr = new PngReader(currentImage);
    PngWriter png = new PngWriter(new FileOutputStream(currentImage), pngr.imgInfo);
    png.getMetadata().setText(key, value);
    return true;
}

但这没有任何作用。

我尝试使用Writing image metadata in Java, preferably PNG

的答案

这有效(有点),但我的阅读功能无法看到它。

2 个答案:

答案 0 :(得分:4)

如果要块添加到图像中,则必须读取并写入完整图像。实施例

PngReader pngr = new PngReader(origFile);
PngWriter pngw = new PngWriter(destFile, pngr.imgInfo, true);
// instruct the writer to copy all ancillary chunks from source
pngw.copyChunksFrom(pngr.getChunksList(), ChunkCopyBehaviour.COPY_ALL);
// add a new textual chunk (can also be done after writing the rows)
pngw.getMetadata().setText("my key", "my val");
// copy all rows
for (int row = 0; row < pngr.imgInfo.rows; row++) {
  IImageLine l1 = pngr.readRow();
  pngw.writeRow(l1);
}
pngr.end(); 
pngw.end();

如果您需要更高的性能,可以在较低级别读取/写入块,请参阅this example

答案 1 :(得分:0)

试试这个:

Stream pngStream = new System.IO.FileStream("smiley.png", FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite);
PngBitmapDecoder pngDecoder = new PngBitmapDecoder(pngStream, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);
BitmapFrame pngFrame = pngDecoder.Frames[0];
InPlaceBitmapMetadataWriter pngInplace = pngFrame.CreateInPlaceBitmapMetadataWriter();
if (pngInplace.TrySave() == true)
{
    pngInplace.SetQuery("/Text/Description", "Have a nice day."); 
}

pngStream.Close();