oozcitak / exiflibrary

A .Net Standard library for editing Exif metadata
MIT License
134 stars 48 forks source link

Does it even work ? #69

Closed chacha21 closed 4 years ago

chacha21 commented 4 years ago

Does it really work ? I checked the sample code below. There are no errors of any kind, but I could not get any metadata added : I checked with ExifTest itself, and Windows explorer File properties : the metadata I try to set is never visible.

With breakpoints, I could not find any place where the "file.Save()" operation is browsing the Exif tags.

            var file = ExifLibrary.ImageFile.FromFile("E:\\test_data\\test.tiff");
            //file.Properties.Set(ExifLibrary.ExifTag.ISOSpeedRatings, (ushort)40);
            file.Properties.Set(ExifLibrary.ExifTag.Artist, "me");
            file.Properties.Set(ExifLibrary.ExifTag.DateTime, System.DateTime.Now);
            //file.Properties.Set(ExifLibrary.ExifTag.DateTimeDigitized, System.DateTime.Now);
            //file.Properties.Set(ExifLibrary.ExifTag.DateTimeOriginal, System.DateTime.Now);
            //file.Properties.Set(ExifLibrary.ExifTag.SubSecTimeOriginal, 40);
            file.Save("E:\\test_data\\test2.tiff");
oozcitak commented 4 years ago

You are right. TIFF file properties are not updated when written back. I am looking into it.

chacha21 commented 4 years ago

It is a little better, but not all tags work. In the following code sample, the "ExifLibrary.ExifTag.DateTime" is correctly retrieved after being written, but neither "ExifLibrary.ExifTag.DateTimeOriginal" nor "ExifLibrary.ExifTag.SubSecTimeOriginal" seem correctly inserted in the TIFF. (I also tried with JPEG, it does not work similarly)

            string path = "E:\\test_data\\test.tiff";
            string path2 = "E:\\test_data\\test2.tiff";
            ExifLibrary.ImageFile imageFile = ExifLibrary.ImageFile.FromFile(path);
            if (imageFile != null)
            {
              System.DateTime pFrameDate1 = new System.DateTime(2020, 01, 02, 12, 34, 56, 999);
              System.DateTime pFrameDate2 = new System.DateTime(2020, 01, 02, 11, 33, 44, 555);
              System.String frameDateString1 = System.String.Format("{0}", pFrameDate1.ToString("yyyy:MM:dd hh:mm:ss"));
              System.String frameDateString2 = System.String.Format("{0}", pFrameDate2.ToString("yyyy:MM:dd hh:mm:ss"));
              imageFile.Properties.Set(ExifLibrary.ExifTag.DateTime, frameDateString1);
              imageFile.Properties.Set(ExifLibrary.ExifTag.DateTimeOriginal, frameDateString2);
              long frameDateTicks = pFrameDate2.Ticks;
              long frameDateFractionTicks = frameDateTicks%System.TimeSpan.TicksPerSecond;
              System.Decimal frameDateFractionDecimal = (new System.Decimal(frameDateFractionTicks))/(new System.Decimal(System.TimeSpan.TicksPerSecond));
              System.String frameDateFractionString = frameDateFractionDecimal.ToString("F8");
              frameDateFractionString = (frameDateFractionString  == null) ? null : frameDateFractionString.Replace("0,", "");
              frameDateFractionString = (frameDateFractionString == null) ? null : frameDateFractionString.Replace("0.", "");
              imageFile.Properties.Set(ExifLibrary.ExifTag.SubSecTimeOriginal, frameDateFractionString);
              imageFile.Save(path2);
              imageFile = null;
            }//end if (imageFile)
oozcitak commented 4 years ago

DateTime and DateTimeOriginal tags should be instances of the DateTime class; not strings. Furthermore DateTimeOriginal and SubSecTimeOriginal tags are JPEG/Exif only and can't be saved in a tiff file.

chacha21 commented 4 years ago

DateTime (...) tags should be instances of the DateTime class; not strings.

Both work, I wanted to be sure that the format was OK, there are various references on the net that sometimes differ from the real standard (https://www.awaresystems.be/imaging/tiff/tifftags/datetime.html)

Furthermore DateTimeOriginal and SubSecTimeOriginal tags are JPEG/Exif only and can't be saved in a tiff file.

I did not know that; however, I could not make it work with JPEG either

Finally, so far I am able to retrieve DateTime with ExifTest, but the Windows Explorer (file properties panel) does not report it; any idea why ?

oozcitak commented 4 years ago

I did not know that; however, I could not make it work with JPEG either

Please take a look at: http://oozcitak.github.io/exiflibrary/articles/TIFFMetadata.html. I tried to separate tags by file types.

Finally, so far I am able to retrieve DateTime with ExifTest, but the Windows Explorer (file properties panel) does not report it; any idea why ?

Windows explorer shows file system dates (date created, date modified) in the detail pane. You should be able to see date taken in the jpeg's details tab (I set this date with your DateTimeOriginal code above):

Untitled

It doesn't seem to show the date tag for tiff files though.

chacha21 commented 4 years ago

Windows explorer shows file system dates (date created, date modified) in the detail pane. You should be able to see date taken in the jpeg's details tab (I set this date with your DateTimeOriginal code above):

That's strange, I can't get the "DateTimeOriginal" work with jpg on my machine... The field is empty in Windows Explorer and is not retrieved by ExifTest.

oozcitak commented 4 years ago

Is it possible to send me the image for testing?

chacha21 commented 4 years ago

https://chachatelier.fr/tmp/test.jpg

oozcitak commented 4 years ago

I can't connect to your server. Can you just zip the image and drag&drop into your reply?

chacha21 commented 4 years ago

test.zip

oozcitak commented 4 years ago

This is a TIFF file, not a jpeg. Its extension is jpg but its content is TIFF.

Edit: https://www.metadata2go.com/result/1d38f707-00d5-41b0-bc8b-1d1a6ba07039

chacha21 commented 4 years ago

Ok, I understand. I must have messed up with Paint.Net. Indeed, I have recreated the jpg and now the Exif tags are OK.

chacha21 commented 4 years ago

DateTime and DateTimeOriginal tags should be instances of the DateTime class; not strings. Furthermore DateTimeOriginal and SubSecTimeOriginal tags are JPEG/Exif only and can't be saved in a tiff file.

What about https://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif.html ? It mentions for instance DateTimeOriginal as a TIFF tag. Is it a reliable source ?

oozcitak commented 4 years ago

The TIFF standard is here: https://www.adobe.io/content/dam/udp/en/open/standards/tiff/TIFF6.pdf. You'll notice there is no DateTimeOriginal tag.

That being said, TIFF is capable of including custom tags. Meaning you can add a DateTimeOriginal tag to a TIFF file, you can even add custom tags with arbitrary data, or even an entire IFD of custom tags. And such a TIFF file would be conforming to the TIFF spec (although it would only be useful to you, as other software wouldn't understand those custom tags).

However, this library in its current form is a Baseline TIFF Reader meaning it only reads and writes the zeroth IFD. Also it doesn't write custom tags, since it wouldn't know where to place -for example- the DateTimeOriginal tag in the TIFF file. So, it just omits custom tags when writing to disk.

Of course, you can fork and modify the code so that you can read and write DateTimeOriginal or other custom tags you need. Or you can add the missing functionality to read/write custom tags (maybe multiple IFDs too?) and send me a PR, which would be greatly appreciated.

chacha21 commented 4 years ago

I think that I understood why the Windows Explorer does not display correctly the TIFF tags as set by a tool like yours. It seems that Microsoft is NOT using the native tags but XmpMetadata. See here how they handle that : https://docs.microsoft.com/en-us/dotnet/api/system.windows.media.imaging.inplacebitmapmetadatawriter?view=netcore-3.1

This is just for information, I don't expect your EXIF tool to handle Xmp !