kamadak / exif-rs

Exif parsing library written in pure Rust
BSD 2-Clause "Simplified" License
190 stars 42 forks source link

Plans to add support for writing tags? #1

Open Ortham opened 7 years ago

Ortham commented 7 years ago

I forked rexif to add support for writing GPS tags to it, but upstream hasn't been touched in over a year, the only tests it has are the ones I've added, and I've had to spend time improving the implementation. On the other hand, this library seems to have come on leaps and bounds since I last saw it, and I'm wondering if I should maybe switch my efforts.

Do you plan on adding write support, and if not, would you be interested in a pull request adding it?

kamadak commented 7 years ago

It depends on your use case.

If you are writing Exif data from scratch, it is easy. I will add some support. (Actually, I have scribbled a pre-pre-pre-alpha-quality encoder before, so I need to salvage it...)

If you are modifying existing data, the situation becomes tricky. The problem is that some opaque fields (e.g., MakerNote) may have non-relative offsets in them and they are broken if their positions are changed, unless we deep-inspect and rewrite them. A well-known heuristic is to keep the absolute positions of such fields while reencoding the Exif structure, but it is bothersome. 😫

If you only add GPS tags, the easiest way might be to implement a special logic only for that.

Ortham commented 7 years ago

It would be modifying existing data, I didn't think about non-relative offsets... My use-case only requires writing GPS tags, and since they sit separately, special logic would probably be best for them.

kamadak commented 7 years ago

I have checked in the experimental support for the former use case. For the latter, I will think about it but it will take some time, so I am also welcome for pull requests.

Ortham commented 7 years ago

Thanks, I'll check it out when I get the chance. 👍

bosschaert commented 4 years ago

This is a very old issue. I'm just wondering if there are any plans to implement it?

I'm just looking to write date/time exif information in case it's missing...

Ortham commented 4 years ago

I abandoned the project that involved needing to write EXIF data before I made much progress (and I was only looking at GPS tags anyway).

bosschaert commented 4 years ago

It seems like the https://github.com/liamstask/imagemeta-rs project has some support for it, but that one looks abandoned as well...

kamadak commented 4 years ago

The following steps mostly work, except that MakerNote of some makes will be broken. Do no do this unless relocation of MakerNote is known to be safe with your camera.

  1. Parse the file with Reader.
  2. Create an Writer instance.
  3. Iterate over Reader::fields and feed them into Writer::push_field, with filtering out the tags you want to update.
  4. Prepare the new contents of tags you want to update/add, and feed them into Writer::push_field.
  5. Get the thumbnail image from Reader (see get_jpeg and get_strips functions in tests/rwrcmp.rs) and feed it into Writer::set_jpeg or Writer::set_strips.
  6. Serialize the Exif data with Writer::write.
  7. Replace the old Exif data in JPEG with the new one.

Missing pieces are:

bosschaert commented 4 years ago

Thanks @kamadak for the details. On point 7, do you know a JPEG library that would be able to do this? I looked around and found https://github.com/image-rs/image but I could not find a way using that library to set the EXIF data...

kamadak commented 4 years ago

I have thought there must be some, but I searched on the web to find nothing in Rust.

Enhancing the encoder of the image library you mentioned seems very easy. Just add an APP1 segment with Exif marker + Exif data around here: https://github.com/image-rs/image/blob/cf0cb54ef4d12526091e5c61768da0624615b446/src/jpeg/encoder.rs#L384-L385. On the other hand, I did not find a functionality in that library to embed metadata without decoding/encoding cycle, which we want to avoid because the image quality may degrade.

NelDav commented 4 years ago

Thanks @kamadak for the details. On point 7, do you know a JPEG library that would be able to do this? I looked around and found https://github.com/image-rs/image but I could not find a way using that library to set the EXIF data...

I think you search something like img-parts

paolobarbolini commented 4 years ago

img-parts author here. Thanks @NelDav for mentioning my crate.

As you said img-parts can be used to read and write raw EXIF data to images. It currently supports JPEG, PNG and WEBP, with more formats to come in the future. You can use this crate to generate the raw data and have it written to the file through my crate, as shown in the example

sophie-h commented 9 months ago

Thanks for those detailed instructions on how to update EXIF data!

For some images, I got the exact same binary size for the rewritten raw data. For others, I didn't. Is this expected or does that mean I'm missing some data in the new EXIF?

It also looks like the order of fields changes. Is that correct and if so, is that avoidable?

5. Get the thumbnail image from Reader (see get_jpeg and get_strips functions in tests/rwrcmp.rs) and feed it into Writer::set_jpeg or Writer::set_strips.

Would you accept a PR adding those functions to either experimental or Reader?