我正在研究图像以对它们进行排名。最初我编写了一个数据集来存储图像元数据。当我必须提取图像的元数据时,我遇到了一个问题。我能够提取除了需要对图像进行排名的“标签”字段之外的所有元数据。
我将链接附加到类似的帖子,但它是在matlab中。 Extracting meta data "tags field"
我只需要用红色包围的信息。
答案 0 :(得分:2)
简单地通过meme:“人们不会简单地提取标签元数据”,显然。
根据我的发现,在JPG的属性页面上从资源管理器中设置的标记元数据相对容易获得。
它们位于标识为PropertyItem
的{{1}}中(或十进制中的9C9E
)
此40094
的值是带有Unicode字符的PropertyItem
,并且以空值终止。
以下是一种提取标记的方法(byte[]
分隔,因此您可以根据需要调整方法以返回分割的列表
;
使用此sample image,您应该获得
的字符串输出TagOne; TagTwo:
然而您可能已经注意到我在谈论在Windows资源管理器中设置的基本标记信息和标记。它们很容易获得。
如果您在this sample或this sample上运行上述代码,则无法获得任何数据。这是因为所有各种工具和硬件都可以通过大量不同的方式将元数据存储在jpeg中
如果您想了解有多少不同类型的元数据以及标签及其格式的所有不同名称,请转到ExifTool by Phil Harvey,在该页面上稍微探讨一下,尤其是“标签名称”页面,你肯定会对大量不同的标签感到头疼。
现在你可能想知道你是否应该深入研究元数据标签提取的世界,或者你是否可以为该工具制作一个包装器,将它集成到C#中(显然有些已经完成,但要求工具存在)和其他事项一样,请查看工具页面的Additional Resources部分以获取信息。)
啊,但不要害怕!有人在C#中找到了一种更简单的方法来提取正确的信息,以便您可以单独使用元数据标签。调用库时得到的private string ReadBasicTags(string filename)
{
string foundTags = string.Empty;
using (Image inputImage = new Bitmap(filename))
{
try
{
PropertyItem basicTag = inputImage.GetPropertyItem(40094); // Hex 9C9E
if (basicTag != null)
{
foundTags = Encoding.Unicode.GetString(basicTag.Value).Replace("\0", string.Empty);
}
}
// ArgumentException is thrown when GetPropertyItem(int) is not found
catch (ArgumentException)
{
// finalOutput = "Tags not found";
}
}
return foundTags;
}
会分别为每个标记提供。
作为示例,图像Arena Chapel frescoes(example027.jpg)和Getty Villa(GettyVilla0001.JPG)使用显示的代码生成以下列表:
List<string>
中世纪
意大利
绘画(视觉作品)
壁画(绘画)
壁画(技术)
寓言
建筑室内设计 循环或系列
新约
旧约和旧约 圣人
耶稣基督
玛丽,祝福圣母 圣
基督教肖像作品 激情
犹大加略人 门徒
JpegMetadataAdapter metaAdapter = new JpegMetadataAdapter(@"C:\Dev\example027.JPG");
foreach (string item in metaAdapter.Metadata.Keywords)
{
outputString += string.Format("{0}{1}", item, Environment.NewLine);
}
日落
阴影
壁画
peristyles(柱廊)
视觉陷阱
希腊
罗马
盖蒂别墅
这两个图像都以不同方式存储元数据标签,因此可以公平地说,使用该库时, jpegs 中的元数据标签的大多数版本都应该涵盖这些标记。