Snhp9
Snhp9

Reputation: 539

How can I write metadata to png Image

I have been trying to find a way to write metadata to a PNG and I have tried quite alot.

I can read the data using the pngj library using:

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();

And it works great. But I need to write to it.

I have tried:

    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;
}

But this does nothing.

And I have tried using the answer from Writing image metadata in Java, preferably PNG

this works (kinda) but my read function cant see it.

Upvotes: 2

Views: 2511

Answers (2)

leonbloy
leonbloy

Reputation: 76026

If you want to add a chunk to the image, you must read and write the full image. Example

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();

If you need more performance, you can read/write the chunks at a lower level, see this example.

Upvotes: 4

real_yggdrasil
real_yggdrasil

Reputation: 1263

Try this:

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();

Upvotes: 0

Related Questions