TechnikTobi / little_exif

A little library for reading and writing EXIF data in pure Rust.
Apache License 2.0
20 stars 5 forks source link

Can't write ImageDescription #15

Closed TechnikTobi closed 4 days ago

TechnikTobi commented 5 days ago

now I used the example code from the readme file to write an image description to this file.

    let mut metadata = Metadata::new();
    metadata.set_tag(ExifTag::ImageDescription("Hello World!".to_string()));
    let res = metadata.write_to_file(std::path::Path::new(&file_path));
    println!("res: {:?}", res);

This does work without an error.

But then trying to read that file again with the "little_exif" code that worked before gets the error message:

thread 'main' panicked at C:\Users\mschnell\.cargo\registry\src\index.crates.io-6f17d22bba15001f\little_exif-0.4.1\src\metadata.rs:461:70:
range end index 2 out of range for slice of length 0

writing to the file made it from length 782701 to length 781906. The picture still can be shown and Windows Explorer indeed show "Hello World!" as "Betreff" (which before had been "Thumbs Annotation" ). But the ThumbsPlus software does not show any fields any more. Several Fields Explorer shows have been stayed intact, but the fields Auflösungseinheit Farbdardstellung Kamerahersteller Kameramodell Blendenzahl ISO Lichtwert Brennweite Maximale Blende Messmodus ... (and many more) Exif-Version (had been 0232)

are empty now.

_Originally posted by @mschnell1 in https://github.com/TechnikTobi/little_exif/issues/11#issuecomment-2370972854_

Just to get this straight: The image located at https://bitvibe.de/Upload/IMG_20240828_184255.jpg is the file before the ImageDescription has been changed?

TechnikTobi commented 5 days ago

I was able to reproduce this issue and already released a fix for this in version 0.4.2

mschnell1 commented 4 days ago

Just to get this straight: The image located at https://bitvibe.de/Upload/IMG_20240828_184255.jpg is the file before the ImageDescription has been changed?

This is the "other one", that "Little" could not read right away, even after the update

mschnell1 commented 4 days ago

I was able to reproduce this issue and already released a fix for this in version 0.4.2 Going to try this ASAP....

mschnell1 commented 4 days ago

..... Yep. No "Panic" any more.

Thumbsplus does not "see" the "Hello World", nor the other (original) tags. Explorer does see "Hello World" in two tags "Beschreibung" and "Betreff".

The file got some 4 K Byte smaller. I doubt that is intended. (I suppose the 0.4.2 Update was only regarding the read functionality, not the writing.)

To update or insert a single Tag, to I need to read all of them (here:40) and re-insert them before writing ?

going to do more tests ASAP....

And now "Little" can show the tags in the "Xiaomi" file.

TechnikTobi commented 4 days ago

To insert/update a single tag while keeping the rest, do

let mut metadata = Metadata::new_from_path(&some_image_path).unwrap();
metadata.set_tag(ExifTag::ImageDescription("Hello World!".to_string()));
metadata.write_to_file(& some_image_path)?;

instead of creating a new metadata struct with Metadata::new(). This way, the other tags that have previously been read will be reinserted when writing the metadata back to the image file.

mschnell1 commented 4 days ago

Works !

Great ! Thanks a lot for your hard work !

Just a question: While trying to re-insert the read tags into the Metadata struct, I seemed not to be able to do that as set_tag() does not want a reference, and I seem not to be able to create an ExifTag from an &ExifTag by clone(). As it might be useful to create a vector of ExifTags from the Metadata read, (which also needs clones of the &ExtifTags got from .data() ) I wonder how to do this. (Maybe Copy needs to be implemented for ExifTag... )

Thanks again !

TechnikTobi commented 4 days ago

I added a derive for Clone on the ExifTag in version 0.4.3 - is that sufficient for your use case? Deriving Copy is less trivial as this requires an implementation of Copy for Vec<u16>, Vec<u32>, ... as well. If that answers your question I'll close this issue and #14.

And now "Little" can show the tags in the "Xiaomi" file.

In that case I'll close issue #13 as well - or is there anything else related to that open from your side?

mschnell1 commented 4 days ago

Perfect ! Now i can construct a vec with all tags read just by fields.push(field.clone()); !

Up till now I checked only a few picture files. With this project I need to handle some thousand. If problems arise I can re-open the issue if necessary.

To me this crate does not seem "little", but decently sophisticated. 🥇

TechnikTobi commented 4 days ago

If a new/unrelated problem arises I'd prefer a new issue instead of reopening a closed one. And thanks for the compliment ;)