我正在尝试获取给定图像中所有EXIF
标记的列表。
使用Image.propertyItems[]
数组,我可以枚举图像对象实例读取的所有项目,并输出它们的ID。
我看到有些项目没有列在那里,包括Windows资源管理器在内的其他应用程序似乎没有问题检索。
E.G。在以下代码中......
Image img = new Bitmap("C:\\IMAG0648.jpg");
foreach (PropertyItem property in img.PropertyItems)
{
Trace.WriteLine(property.Id);
}
我得到了大多数项目的列表,特别是虽然我遗漏了0x010F
和0x0110
(可能还有其他人)。我知道这些项是因为我可以在另一个EXIF编辑器(如PhotoME)中打开相同的图像,它们显然在那里,并且清楚地标记为正确的ID。
EXIF
中是否存在嵌套级别,而且我没有走得太远,或者是否有某些原因导致上述基本形式不起作用?
答案 0 :(得分:2)
尝试ExifLib - 有一个带源代码的演示项目,可以从您可以使用的图像中提取所有标记。
编辑:我将附上我的答案来解释为什么我认为.Net Image类不能像我们预期的那样处理所有EXIF标记。但是,我将在上面留下我的初步链接和建议,因为我认为它最终是最好的选择。
好的,关于为什么:
我在下面描述的测试使用了Windows 7显示制作和模型的EXIF数据的图像(通过右键单击文件>属性>'详细信息'选项卡>'相机'部分),但在.Net中{{1不包含这些相同的EXIF标记。在另一个答案中提到了使用HTC One拍摄的图像,因此我找到了满足我的测试here的图像。 (具体来说,我从这个网页上使用了原版2.jpg,原版4.jpg和原版8.jpg。)
首先,我看了PropertyItems
并得到了32.所以那里有数据! (显然,我们知道Windows 7在我的情况下会看到EXIF标签)。但是,当我遍历img.PropertyItems.Count()
并查看每个.PropertyItems
时(根据您原来的问题):
Id
我会获得SoftwareUsed(或者如果我使用206,我会获得DateTime)EXIF属性那么,到目前为止,为什么.Net Image类没有看到ID为271/272的EXIF标签(同样是Camera Make / Model)?
我深入研究了ExifLib的源代码(回答顶部的链接)并认为我看到了正在发生的事情:
img.PropertyItems.Single(x => x.Id == 305).Value
方法(第655行),您会看到字节偏移用于查找“Exif IDF”和每个标记的总空间因此,当不是任何字节偏移时,.Net Image类似乎能够通过private byte[] GetTagBytes(...)
正确返回EXIF标记。
使用ExifDataView(http://www.nirsoft.net/utils/exif_data_view.html)我能够验证这一点:
ExifLib代码正确处理这些偏移和/或多个空字符,而.Net则没有。
结果是.Net Image类不会作为PropertyItems
的一部分迭代这些属性,并在使用PropertyItems
时返回'Sequence contains no matching element'
底线:如果您希望正确处理所有图像,请使用ExifLib或其他一些专门用于处理提取EXIF数据的第三方库。如果你希望它在字节恰到好处的某些时候工作,请使用.Net Image类: - )
答案 1 :(得分:1)
根据the documentation,您指定的标签肯定存在。这对this sample image
有用
int tagMake = 0x010F; // 271
int tagModel = 0x0110; // 272
Image image = Image.FromFile(@"C:\image.jpg");
byte[] make = image.PropertyItems.Single(x => x.Id == tagMake).Value;
byte[] model = image.PropertyItems.Single(x => x.Id == tagModel).Value;
var encoding = new System.Text.ASCIIEncoding();
Console.WriteLine(encoding.GetString(make)); // Returns: Canon
Console.WriteLine(encoding.GetString(model)); // Returns: Canon PowerShot S40