“拍摄日期”未显示在图像 PropertyItems 中,而它显示在 Windows 资源管理器的文件详细信息(文件属性)中
Posted
技术标签:
【中文标题】“拍摄日期”未显示在图像 PropertyItems 中,而它显示在 Windows 资源管理器的文件详细信息(文件属性)中【英文标题】:"Date Taken" not showing up in Image PropertyItems while it shows in file details (file properties) in Windows Explorer 【发布时间】:2013-01-13 21:21:17 【问题描述】:我有点惊讶和疑惑。我尝试从图像中读取属性项。特别是,我对“拍摄日期”感兴趣。我已经写了一个程序来做到这一点。或多或少。对于某些文件,它可以完美运行,但是...
我有一些文件在属性中有“使用日期”(当通过 Windows 资源管理器查看时,Windows 7 x64)。它们不同于创建、修改和访问的日期。所以我确实有第四次约会。 但是,如果我遍历属性项,它不会显示(在任何 ID 上)。 当我在 PropertyItem.Id(0x9003 或 36867)上查找它时,我发现该属性项不存在。
我的代码循环遍历属性项:
for (int i = 0; i < fileNames.Length; i++)
FileStream fs = new FileStream(fileNames[i], FileMode.Open, FileAccess.Read);
Image pic = Image.FromStream(fs, false, false);
int t = 0;
foreach (PropertyItem pii in pic.PropertyItems)
MessageBox.Show(encoding.GetString(pii.Value, 0, pii.Len - 1) + " - ID: " + t.ToString());
t++;
只读取“Date Taken”属性的代码(我从这里偷来的:http://snipplr.com/view/25074/)
public static DateTime DateTaken(Image getImage)
int DateTakenValue = 0x9003; //36867;
if (!getImage.PropertyIdList.Contains(DateTakenValue))
return DateTime.Parse("01-01-2000");
string dateTakenTag = System.Text.Encoding.ASCII.GetString(getImage.GetPropertyItem(DateTakenValue).Value);
string[] parts = dateTakenTag.Split(':', ' ');
int year = int.Parse(parts[0]);
int month = int.Parse(parts[1]);
int day = int.Parse(parts[2]);
int hour = int.Parse(parts[3]);
int minute = int.Parse(parts[4]);
int second = int.Parse(parts[5]);
return new DateTime(year, month, day, hour, minute, second);
但是,当我在 Windows 资源管理器的“文件属性窗口”中更改日期时,它开始显示在我的程序中。
所以我的问题是:这个“拍摄日期”来自哪里?我怎样才能访问它?难道除了 EFIX 数据之外还有其他信息来源吗?
谢谢!
【问题讨论】:
看看本页信息能不能帮到你***.com/questions/180030/… |或查看此链接Getting Picture Properties 【参考方案1】:如果你想从一些基本的编码开始,你可以尝试这样的事情
// 加载你喜欢的图像。 System.Drawing.Image image = new Bitmap("my-picture.jpg");
Referenced from AbbydonKrafts
// Get the Date Created property
//System.Drawing.Imaging.PropertyItem propertyItem = image.GetPropertyItem( 0x132 );
System.Drawing.Imaging.PropertyItem propertyItem
= image.PropertyItems.FirstOrDefault(i => i.Id == 0x132 );
if( propItem != null )
// Extract the property value as a String.
System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
string text = encoding.GetString(propertyItem.Value, 0, propertyItem.Len - 1 );
// Parse the date and time.
System.Globalization.CultureInfo provider = CultureInfo.InvariantCulture;
DateTime dateCreated = DateTime.ParseExact( text, "yyyy:MM:d H:m:s", provider );
【讨论】:
伙计,这正是我在过去几年中一直在尝试使用 qQuery 做的事情,但遇到了很多问题。很好的答案,谢谢(不敢相信这还没有被赞成和接受) 我正在使用这个解决方案,并且我不断地反复运行相同的测试以检查它是否有效,并且大约一半的时间图像上的 PropertyItems 属性是一个空数组。你知道为什么会这样吗?正在上传相同的图像并运行相同的测试。 您是在单步执行代码吗..?你知道你是否有空值或空值的东西没有在你期望的地方持续存在..?您正在运行程序中的什么事件或进程...? 是的,我正在逐步执行代码,基本上该过程是通过 WebApi 上传文件。它进入我的控制器,我创建了一个字节数组。当它进入服务层时,我运行这个方法,它将它变成一个图像,这就是我设置断点的地方。有时它会随机为空,有时它会有 28 个值。 我之前遇到过这个问题,我解决它的方法是在更新面板中添加上传控件并将更新面板的模式设置为条件.. 我还有另一种方法也可以几周前已经完成了,但我的个人机器在家里。我会尽量记住周一回到这里并发布该示例【参考方案2】:嗯,我正在获取图像文件的“修改”日期,而不是拍摄日期。 我已经使用以下代码实现了:
public static System.DateTime GetImageDate(string filePath)
System.Drawing.Image myImage = Image.FromFile(filePath);
System.Drawing.Imaging.PropertyItem propItem = myImage.GetPropertyItem(36867);
string dateTaken = new System.Text.RegularExpressions.Regex(":").Replace(System.Text.Encoding.UTF8.GetString(propItem.Value), "-", 2);
return System.DateTime.Parse(dateTaken);
【讨论】:
【参考方案3】:将.ParseExact
行更改为以下内容
DateTime dateCreated = DateTime.ParseExact( ConvertToString(dateTakenProperty)**.Substring(0, 19)**, "yyyy:MM:dd HH:mm:ss", provider )
在字符串的末尾可能有一个无法处理的null
字符。为预期长度执行.SubString
将解决它。
【讨论】:
以上是关于“拍摄日期”未显示在图像 PropertyItems 中,而它显示在 Windows 资源管理器的文件详细信息(文件属性)中的主要内容,如果未能解决你的问题,请参考以下文章