Search code examples
c#bitmapexif

Changing "DateTaken" of a photo


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;
    }

Solution

  • 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