更改 "DateTaken" 一张照片
Changing "DateTaken" of a photo
我刚从美国旅行回来,在编辑所有照片后,我发现相机使用的是以色列时区,而不是美国时区。有7个小时的时差,所以这对我来说是个大问题。我有 175GB 的照片,但我关心 "only" 大约 350 张照片。我无法手动编辑它们的 EXIF,所以我考虑使用 C#。
这个想法是它会读取每张照片的 EXIF,获取时间,并在原始照片中将时间设置为负 7 小时。我尝试使用图像 class,但它不起作用。我尝试使用 bitmapMetadate,它成功了!我设法抽出时间做了零下七个小时,但我不知道如何节省时间。我该怎么做?谢谢!
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;
}
不完全是编程解决方案,但您可以使用 exiftool。我正是出于这个目的使用它。
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
您还可以设置 TimeZoneOffset 字段,以防有实际使用它的软件。
我发现的最简单的方法是使用 here 和 System.Drawing.Bitmap;
中描述的技术
代码应该是这样的:
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") + '[=10=]');
DataTakenProperty2.Value = _Encoding.GetBytes(originalDate.ToString("yyyy:MM:dd HH:mm:ss") + '[=10=]');
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();
}
不要忘记添加 System.Drawing 程序集。
如果需要,您可能还需要根据您的文化调整 DateTime 格式
对于 .NET Core,我使用 NuGet 包 ExifLibNet (https://github.com/oozcitak/exiflibrary)
PM> 安装包 ExifLibNet
// using ExifLibrary;
var file = ImageFile.FromFile(filename);
file.Properties.Set(ExifTag.DateTimeDigitized, dateTime);
file.Properties.Set(ExifTag.DateTimeOriginal, dateTime);
file.Save(filename);
我刚从美国旅行回来,在编辑所有照片后,我发现相机使用的是以色列时区,而不是美国时区。有7个小时的时差,所以这对我来说是个大问题。我有 175GB 的照片,但我关心 "only" 大约 350 张照片。我无法手动编辑它们的 EXIF,所以我考虑使用 C#。
这个想法是它会读取每张照片的 EXIF,获取时间,并在原始照片中将时间设置为负 7 小时。我尝试使用图像 class,但它不起作用。我尝试使用 bitmapMetadate,它成功了!我设法抽出时间做了零下七个小时,但我不知道如何节省时间。我该怎么做?谢谢!
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;
}
不完全是编程解决方案,但您可以使用 exiftool。我正是出于这个目的使用它。
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
您还可以设置 TimeZoneOffset 字段,以防有实际使用它的软件。
我发现的最简单的方法是使用 here 和 System.Drawing.Bitmap;
中描述的技术代码应该是这样的:
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") + '[=10=]');
DataTakenProperty2.Value = _Encoding.GetBytes(originalDate.ToString("yyyy:MM:dd HH:mm:ss") + '[=10=]');
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();
}
不要忘记添加 System.Drawing 程序集。 如果需要,您可能还需要根据您的文化调整 DateTime 格式
对于 .NET Core,我使用 NuGet 包 ExifLibNet (https://github.com/oozcitak/exiflibrary)
PM> 安装包 ExifLibNet
// using ExifLibrary;
var file = ImageFile.FromFile(filename);
file.Properties.Set(ExifTag.DateTimeDigitized, dateTime);
file.Properties.Set(ExifTag.DateTimeOriginal, dateTime);
file.Save(filename);