在Windows XP中,"FileInfo.LastWriteTime"将返回拍摄照片的日期 - 无论文件在文件系统中移动多少次.
在Vista中,它返回从相机复制图片的日期.
如何在Vista中拍摄照片?在Windows资源管理器中,此字段称为"采取日期".
这里尽可能快速而干净.通过使用FileStream,您可以告诉GDI +不要加载整个图像以进行验证.它在我的机器上运行速度超过10倍.
//we init this once so that if the function is repeatedly called //it isn't stressing the garbage man private static Regex r = new Regex(":"); //retrieves the datetime WITHOUT loading the whole image public static DateTime GetDateTakenFromImage(string path) { using (FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read)) using (Image myImage = Image.FromStream(fs, false, false)) { PropertyItem propItem = myImage.GetPropertyItem(36867); string dateTaken = r.Replace(Encoding.UTF8.GetString(propItem.Value), "-", 2); return DateTime.Parse(dateTaken); } }
是的,正确的ID是36867,而不是306.
下面的其他开源项目应该注意到这一点.处理数千个文件时,这是一个巨大的性能!
Image myImage = Image.FromFile(@"C:\temp\IMG_0325.JPG"); PropertyItem propItem = myImage.GetPropertyItem(306); DateTime dtaken; //Convert date taken metadata to a DateTime object string sdate = Encoding.UTF8.GetString(propItem.Value).Trim(); string secondhalf = sdate.Substring(sdate.IndexOf(" "), (sdate.Length - sdate.IndexOf(" "))); string firsthalf = sdate.Substring(0, 10); firsthalf = firsthalf.Replace(":", "-"); sdate = firsthalf + secondhalf; dtaken = DateTime.Parse(sdate);
自2002年以来,我维护了一个简单的开源库,用于从图像/视频文件中提取元数据.
// Read all metadata from the image var directories = ImageMetadataReader.ReadMetadata(stream); // Find the so-called Exif "SubIFD" (which may be null) var subIfdDirectory = directories.OfType().FirstOrDefault(); // Read the DateTime tag value var dateTime = subIfdDirectory?.GetDateTime(ExifDirectoryBase.TagDateTimeOriginal);
在我的基准测试中,此代码运行Image.GetPropertyItem
速度比WPF JpegBitmapDecoder
/ BitmapMetadata
API 快12倍,并且快了约17倍.
图书馆提供了大量额外信息,如相机设置(F-stop,ISO,快门速度,闪光模式,焦距......),图像属性(尺寸,像素配置)以及其他诸如GPS位置等信息,关键字,版权信息等
如果您只对元数据感兴趣,那么使用此库非常快,因为它不会解码图像(即位图).如果存储空间足够快,您可以在几秒钟内扫描数千张图像.
ImageMetadataReader
了解许多文件类型(JPEG,PNG,GIF,BMP,TIFF,PCX,WebP,ICO ......).如果您知道自己正在使用JPEG,并且只需要Exif数据,那么您可以使用以下内容更快地完成此过程:
var directories = JpegMetadataReader.ReadMetadata(stream, new[] { new ExifReader() });
该元数据提取库通过可用的NuGet和代码是在GitHub上.感谢所有令人惊叹的贡献者,他们多年来改进了图书馆并提交了测试图像.
使用WPF和C#,您可以使用BitmapMetadata类获取Date Taken属性:
MSDN - BitmapMetada
WPF和BitmapMetadata