Reputation:
I just came back from a trip to the US, and after editing all the photos, I noticed that the camera used the Israeli time zone, and not the american. There is a 7 hours time difference, so it's a big problem for me. I have 175GB of photos, but I care "only" about 350 photos. I can't edit their EXIF manually, so I thought about using C#.
The idea is that it will read each photo's EXIF, get the time, and set the time minus 7 hours in the original photo. I tried using the Image class, but it doesn't work. I tried using the bitmapMetadate, and it worked! I've managed to get the time and do minus seven hours, but I have no idea how to save it. How can I do it? Thanks!
public static string PhotoToBeEdited(FileInfo f)
{
FileStream fs = new FileStream(f.FullName, FileMode.Open, FileAccess.Read, FileShare.Read);
BitmapSource img = BitmapFrame.Create(fs);
BitmapMetadata md = (BitmapMetadata)img.Metadata;
string date = md.DateTaken;
Console.WriteLine(date);
DateTime dt= DateTime.Parse(date);
date = dt.AddHours(-7).ToString();
[...]
return date;
}
Upvotes: 21
Views: 10170
Reputation: 3570
For .NET Core I use NuGet package ExifLibNet (https://github.com/oozcitak/exiflibrary)
PM> Install-Package ExifLibNet
// using ExifLibrary;
var file = ImageFile.FromFile(filename);
file.Properties.Set(ExifTag.DateTimeDigitized, dateTime);
file.Properties.Set(ExifTag.DateTimeOriginal, dateTime);
file.Save(filename);
Upvotes: 9
Reputation: 1385
The simplest way I've found is using technic described here and System.Drawing.Bitmap;
The code should be like this:
public void ChangeDateTaken(string path)
{
Image theImage = new Bitmap(path);
PropertyItem[] propItems = theImage.PropertyItems;
Encoding _Encoding = Encoding.UTF8;
var DataTakenProperty1 = propItems.Where(a => a.Id.ToString("x") == "9004").FirstOrDefault();
var DataTakenProperty2 = propItems.Where(a => a.Id.ToString("x") == "9003").FirstOrDefault();
string originalDateString = _Encoding.GetString(DataTakenProperty1.Value);
originalDateString = originalDateString.Remove(originalDateString.Length - 1);
DateTime originalDate = DateTime.ParseExact(originalDateString, "yyyy:MM:dd HH:mm:ss", null);
originalDate = originalDate.AddHours(-7);
DataTakenProperty1.Value = _Encoding.GetBytes(originalDate.ToString("yyyy:MM:dd HH:mm:ss") + '\0');
DataTakenProperty2.Value = _Encoding.GetBytes(originalDate.ToString("yyyy:MM:dd HH:mm:ss") + '\0');
theImage.SetPropertyItem(DataTakenProperty1);
theImage.SetPropertyItem(DataTakenProperty2);
string new_path = System.IO.Path.GetDirectoryName(path) + "\\_" + System.IO.Path.GetFileName(path);
theImage.Save(new_path);
theImage.Dispose();
}
Don't forget to add System.Drawing assembly. Also you will probably need to adjust DateTime format to your culture, if needed
Upvotes: 18
Reputation: 18633
Not exactly a programming solution, but you can use exiftool. I use it for this exact purpose.
Date/Time Shift Feature
Have you ever forgotten to set the date/time on your digital camera before taking a bunch of pictures? ExifTool has a time shift feature that makes it easy to apply a batch fix to the timestamps of the images (eg. change the "Date Picture Taken" reported by Windows Explorer). Say for example that your camera clock was reset to 2000:01:01 00:00:00 when you put in a new battery at 2005:11:03 10:48:00. Then all of the pictures you took subsequently have timestamps that are wrong by 5 years, 10 months, 2 days, 10 hours and 48 minutes. To fix this, put all of the images in the same directory ("DIR") and run exiftool:
> exiftool "-DateTimeOriginal+=5:10:2 10:48:0" DIR
You can also set the TimeZoneOffset field, in case there's ever software that actually uses it.
Upvotes: 4