1

I'm tying to set the DateTaken parameter with C#, because I've got a lot of photos without this date. I only found this comment changing-datetaken-of-a-photo In this toppic they are changing it and not creating it.

If use this function, but DataTakenProperty1 or DataTakenProperty2 is null and can not be set.

    private static void SetDateTaken(string path, DateTime NEWdate)
    {
        Image theImage = new Bitmap(path);
        PropertyItem[] propItems = theImage.PropertyItems;
        Encoding _Encoding = Encoding.UTF8;

        var DataTakenPropert = propItems.SetValue(NEWdate.ToString("yyyy:MM:dd HH:mm:ss"), ??How do i know the index??);

        theImage.SetPropertyItem(DataTakenProperty);
        string new_path = Path.GetDirectoryName(path) + "\\_" + Path.GetFileName(path);
        theImage.Save(new_path);
        theImage.Dispose();
    }

Thanks for your help

Xandar
  • 21
  • 6

1 Answers1

2

You can acheive this using a little trick, since you can't initiate PropertyItem when its null.

It is difficult to set property items, because the PropertyItem class has no public constructors. One way to work around this restriction is to obtain a PropertyItem by retrieving the PropertyItems property value or calling the GetPropertyItem method of an Image that already has property items. Then you can set the fields of the PropertyItem and pass it to SetPropertyItem.

private static void SetDateTaken(string path, string samplePath, DateTime NEWdate)
{         
    Encoding _Encoding = Encoding.UTF8;
    Image theImage = new Bitmap(path);
    PropertyItem[] propItems = theImage.PropertyItems;

    var DataTakenProperty1 = propItems.FirstOrDefault(a => a.Id.ToString("x") == "9003");
    var DataTakenProperty2 = propItems.FirstOrDefault(a => a.Id.ToString("x") == "9004");

    //// this is where you do the hack
    if (DataTakenProperty1 == null)
    {
        Image sampleImage = new Bitmap(samplePath);
        PropertyItem fakePropertyItem1 = sampleImage.PropertyItems.FirstOrDefault(a => a.Id.ToString("x") == "9003");
        fakePropertyItem1.Value = _Encoding.GetBytes(NEWdate.ToString("yyyy:MM:dd HH:mm:ss") + '\0');
        fakePropertyItem1.Len = fakePropertyItem1.Value.Length;
        theImage.SetPropertyItem(fakePropertyItem1);

        PropertyItem fakePropertyItem2 = sampleImage.PropertyItems.FirstOrDefault(a => a.Id.ToString("x") == "9004");
        fakePropertyItem2.Value = _Encoding.GetBytes(NEWdate.ToString("yyyy:MM:dd HH:mm:ss") + '\0');
        fakePropertyItem2.Len = fakePropertyItem2.Value.Length;
        theImage.SetPropertyItem(fakePropertyItem2);
    }
    else
    {
        DataTakenProperty1.Value = _Encoding.GetBytes(NEWdate.ToString("yyyy:MM:dd HH:mm:ss") + '\0');
        DataTakenProperty2.Value = _Encoding.GetBytes(NEWdate.ToString("yyyy:MM:dd HH:mm:ss") + '\0');
        theImage.SetPropertyItem(DataTakenProperty1);
        theImage.SetPropertyItem(DataTakenProperty2);
    }

    theImage.Save(newPath);
    theImage.Dispose();
}

List of PropertyIds

cdev
  • 5,043
  • 2
  • 33
  • 32
  • Hello, thank you for your help, i'm not getting any error, but unfortantly it's not working. I tried this ID's (also with and without prevois 0x ): 132, 9003, 9004. The DateTaken attribute is still emtpy / explorer isn't showing it – Xandar Oct 18 '19 at 19:50
  • Did you read answer correctly? Above code is tested and it works also – cdev Oct 18 '19 at 23:31
  • hmm, it's not working, I've added "theImage.Save(path); theImage.Dispose();" and nothing happend. Ff I read the dei again and then let me show the ID's, the 9004 is not displayed, only [770, 34675, 20752, 20753, 20754] – Xandar Oct 20 '19 at 08:42
  • I was able to reproduce your problem with png types, but for jpg above modified code is working. SamplePath is jpg with DateTaken property. – cdev Oct 20 '19 at 15:11
  • yes, png is the problem. with jpg it's working fine. Thank you. i've got only a few png pictures – Xandar Oct 30 '19 at 18:37