Project

General

Profile

Best way to save image+metadata into new file

Added by Goran Nagy almost 5 years ago

Hi,

I have an image Image1.jpg. I would like to read metadata, change some of it and then save everything (image + metadata) into new file Image2.jpg (may be in different folder). What would be the best (fastest) way of doing this? writeMetadata saves metadata into same file, which is not what I want. Is it possible to somehow tell exiv2 to use different path for saving?

I am using c++ library, not command line tool.

Thanks
Goran


Replies (5)

RE: Best way to save image+metadata into new file - Added by Robin Mills almost 5 years ago

Yes, you can do that. Take a look at the code in <exiv2dir>/samples/metacopy.cpp to see how to do that.

RE: Best way to save image+metadata into new file - Added by Goran Nagy almost 5 years ago

Sorry for not getting back to you sooner, but only now I had time to check what you suggested.

However, this does not seem like a solution for what I need. I may be wrong though.

Let me explain a bit what my need is. I am evaluating exiv2 for an Android app. When user decides to write metadata (for certain image), the app should write that into temporary file. That temporary file should be all that is written. At this point I don't want to write into original file anything.
This is done in exiv2's native code (obviously). After execution is back to Java, it will then overwrite original file with this temporary file. So, basically there are two writings: once into temporary file (by exiv2) and once overwriting original file (java code).

The way I understand exiv2's code, when writeMetadata() is called it will use it's own temporary file (not always though), and write stuff (image data + metadata) into it, and then it will overwrite original file. Which is similar to what I would like with 2 differences:
  • I want to perform second part in Java code
  • I want to tell exiv2 what temporary file (path) to use

I still haven't find a good way to do that.

In the sample you suggested to check, it reads data from one file and writes it into second file. However, second file needs to exist, and it will only transfer metadata into second file, not image data. At least that's how I understand it.

I suppose I could maybe create myJpegImage which inherits from JpegImage and override JpegBase::writeMetadata():

    void JpegBase::writeMetadata()
    {
        if (io_->open() != 0) {
            throw Error(9, io_->path(), strError());
        }
        IoCloser closer(*io_);
        BasicIo::AutoPtr tempIo(io_->temporary()); // may throw
        assert (tempIo.get() != 0);

        doWriteMetadata(*tempIo); // may throw
        io_->close();
        io_->transfer(*tempIo); // may throw
    } // JpegBase::writeMetadata

Original code (above) uses temporary file, and then transfers data from temporary file to original. By using my own temporary file path and at the end not calling

      io_->transfer(*tempIo); // may throw

it would do what I need: write everything into temporary file, and then stop leaving original file intact.

But the way I understand it, I would need to do this for every format, which seems a lot of work.

So, is there a better way and I am missing something?

RE: Best way to save image+metadata into new file - Added by Robin Mills almost 5 years ago

I need to give this some thought and I'm on vacation in New Zealand at the moment.

It sounds as though you may have to rewrite writeMetadata() for every image type (about 15 of them). That might be quite easy. If you need the same code in each format, it might be straightforward to do something like this:

void JpegBase::writeMetadata()
{
#ifndef USE_GORANS_WRITEMETADATA
... the usual stuff
#else
    goransWriteMetadata();
#endif
}
And put your code into Image::goransWriteMetadata().

You can rewrite BasicIo::temporary() to change the path to the temporary file.

One of objectives for 2017 is to support build/test for mobile (iOS and Android). I've never worked with either of those systems and don't know what's involved. It sounds as though you are well on your way to building Exiv2 for Android. If there's a strong need to jump between Native (C++) and Java code on Android, I'd be interested in adding the USE_GORANS_WRITEMETADATA code to the code in the repos. Of course, it wouldn't be labelled with your name, we'll detect the platform and build appropriately.

Perhaps we could discuss this together on Skype (or FaceTime or Google+) in February when I'm back home in England.

RE: Best way to save image+metadata into new file - Added by Goran Nagy almost 5 years ago

OK, I'll try changing the code myself.

Sure, you can contact me when you come back. I am far from being expert in JNI and native code, but maybe I can be of some help.

RE: Best way to save image+metadata into new file - Added by Robin Mills almost 5 years ago

Together we'll figure this out. I don't know anything about developing for Android, however I know Java quite well have worked with JNI. You'll have to dig around to fix this and I will work with you when I get home. I'll be back at work on January 23. Hopefully we'll find a way to deal with this that becomes part of the code base going forward.

    (1-5/5)