元数据查询语言概述

本主题介绍 Windows 映像组件 (WIC) 的元数据查询语言。 使用元数据查询语言创建表达式,以查找特定数据 (元数据项) 和位置, (元数据块在图像的元数据) 。

本主题包含以下各节:

先决条件

若要了解本主题,应熟悉 WIC 元数据概述和访问元数据中所述的 WIC 元数据 系统,如 读取和写入图像元数据概述中所述。

简介

你主要通过两个组件对象模型 (COM) 组件与元数据平台进行交互:一个查询读取器(由 IWICMetadataQueryReader 接口表示)和一个查询编写器(由 IWICMetadataQueryWriter 接口表示)。 这些组件使你能够使用元数据查询语言读取或写入元数据。 查询语言描述路径表达式的语法,查询组件使用此路径表达式来访问所需的元数据。 此路径表达式描述元数据块或项的位置。

元数据块是特定格式的命名元数据组。 元数据块可以包含单个元数据项,例如作者或创建时间以及其他元数据块。 元数据块的名称由其格式决定。 例如,包含 App1 元数据的元数据块将命名为“app1”。 常见的元数据格式包括 App1、Exif、IFD 和 XMP。

元数据项是描述作者、标题和分级等特征的名称/值对。

路径表达式包含一个或多个元数据块名称。 它还可以在元数据块中指定元数据项。 以下路径表达式表示 App1 块,其中包含包含元数据项的 IFD 块:

  • /app1/ifd/{ushort=18249}

下图演示了具有四个根元数据块的示例 JPEG 图像的构成:App0、App1、XMP 和未知块。 每个突出显示的项都记录 (块或项) 元数据的类型以及用于检索数据的查询表达式。

包含元数据标注的 jpeg 图像

注意

本文档中引用了此关系图的内容,并用于许多示例。

 

路径表达式的剖析

若要使用 WIC API 访问元数据,在大多数情况下必须使用完全限定的查询表达式。 本主题讨论用于访问元数据的完全限定表达式。 如果需要有关使用非完全限定表达式的情况的信息,请参阅本文档后面的照片元数据策略表达式部分。

什么是完全限定的查询表达式? 在 WIC 中,完全限定表达式是一个字符串,以 /) (路径字符斜杠开头,后跟元数据块或特定元数据项的导航路径。 导航路径中的每个步骤由斜杠分隔,形成用于访问元数据块或元数据项的表达式。 例如,下面是一个完全限定的查询表达式,该表达式访问嵌套在 App1 块中的 IFD 块中的 Microsoft 照片分级:

  • /app1/ifd/{ushort=18249}

当 WIC 分析此表达式时,它首先在图像的元数据中搜索 App1 元数据块。 如果找到 App1 块,它会继续搜索嵌套的 IFD 元数据块。 如果找到 IFD 块,它会在 IFD 元数据块内查找特定的元数据项,在本例中为标记 18249 下的 MicrosoftPhoto 分级。 如果 WIC 在任何时候找不到元数据块或项,则会中止查询。

块选择

最简单的 WIC 元数据查询表达式是一个表达式,用于获取特定元数据块的查询读取器/编写器。 通过获取查询读取器/编写器,可以将后续查询直接定向到嵌套元数据块,而无需处理其父块。 块选择查询表达式是指向所需元数据块的导航路径。 例如,在上图中,有五个元数据块,其中两个嵌套在其他元数据块中。 下面是 JPEG 示例中每个元数据块的路径表达式:

  • /app0
  • /app1
  • /app1/ifd
  • /app1/ifd/exif
  • /xmp

使用查询读取器/编写器执行查询时,它将返回一个新的查询读取器/编写器,该读取器/编写器为指定元数据块范围内的查询提供服务。 例如,如果执行查询“/app1”,则会获取新的查询读取器,并且对新读取器的查询相对于 App1 块。 这意味着查询“/ifd”对新读取器有效,因为 App1 块包含 IFD 块。 但是,“/xmp”不起作用,因为此 App1 块不包含 XMP 元数据块。

查询语言还支持索引表示法。 当存在多个相同类型的块时,索引表示法提供对特定元数据块的访问。 对于 JPEG 示例,可以使用以下索引路径表达式:

  • /[0]app1/[0]ifd

在查询语言中,所有索引都从零开始。 在前面的表达式中,第一个 App1 块的第一个零查询和第二个零查询查询第一个嵌套的 IFD 块。 即使不存在同一类型的多个块,仍可以使用索引表示法。 如果示例 JPEG 包含具有嵌入式 IFD 块的第二个 App1 块,则表达式“/[1]app1/ifd”将用于访问第二个 App1 块。

索引表示法在处理 PNG tEXt 区块时变得更加常见,因为 PNG 映像可能具有多个 tEXt 区块。

注意

不支持多维数组索引。

 

项目选择

可以通过在块选择表达式上构建来访问元数据块中的元数据项。 请考虑 JPEG 示例中的 XMP 和 Microsoft 照片分级属性。 此元数据存在于两个元数据块中:App1/IFD 和 XMP 块。 因此,可以使用多个表达式来访问相同的数据。 以下表达式访问 XMP 块中的 MicrosoftPhoto 分级:

  • /xmp/xmp:Rating

表达式的“xmp:”部分是架构友好的标识符。 XMP 是一种可扩展的标准,允许第三方实体发布自己的架构,用于定义如何存储某些元数据项。 XMP 架构由 URL 完全标识,但 WIC 为已知架构提供一组友好标识符。 有关详细信息,请参阅 本机图像格式元数据查询 主题。

对于 JPEG 图像,分级信息也可以存储在 App1 嵌套 IFD 块中。 但是,与 XMP 分级示例不同,IFD 块不使用架构名称来访问分级信息。 请改用数据表达式。 以下表达式用于访问 App1 嵌套 IFD 块中的 MicrosoftPhoto 分级:

  • /app1/ifd/{ushort=18249}

在此表达式中,表达式的“/app1/ifd”部分是指向 IFD 块 (的导航路径,如前面在块选择部分) 中所述。 表达式“/{ushort=18249}”的第二部分访问数据。 表达式的这一部分指示查询分析程序查找嵌入到标记标识符为 18249 的无符号短标记中的数据。

注意

有关每种图像格式支持的常见元数据格式的列表,请参阅 本机图像格式元数据查询 主题。

 

{ushort=18249} 是数据表达式,可以采用多种形式。 数据表达式是包含请求的元数据标记或键(在本例中为“18249”)和键的数据类型(在本例中为“ushort”)的两部分表达式。 这两个部分由等号分隔 (=) 。 WICs 支持大多数常见的 C/C++ 数据类型。 查询语言接受以下数据类型:

  • char
  • uchar
  • short
  • ushort
  • long
  • ulong
  • int
  • uint
  • longlong
  • FLOAT
  • Double
  • str
  • wstr
  • guid
  • bool

注意

此列表仅指定元数据查询语言支持的数据类型。 创建元数据查询数据表达式(例如 {ushort=18249})时,请使用这些数据类型。 WIC 以 PROPVARIANT 的形式返回元数据项的值,后者定义其自己的类型系统。

 

示例中的“18249”是数据标记。 此特定数字由 Microsoft 定义,以包含 MicrosoftPhoto 分级。 数据标记可以是任意数字、字符串或 GUID,具体取决于要查找的数据项

与 XMP 分级示例不同,App1/IFD 块中的分级值没有名称冲突。 这是因为 XMP 分级值实际上存储在不同的 ushort 标记 18246 下。 因此,用于访问 App1/IFD 块中的 XMP 分级的表达式为:

  • /app1/ifd/{ushort=18246}

注意

有关元数据查询语言的正式说明,请参阅本文档后面的元数据查询语言摘要部分。

 

转义字符

查询语言不区分大小写,并且将所有字符视为小写。 但是,某些元数据格式 ((如 XMP) )区分大小写。 使用区分大小写的元数据格式时,如果要指定大写字符,请使用反斜杠 (\) 字符。

转义字符由语言分析程序使用,并直接解释其后面的以下字符。 例如,表达式 {char=\\} 解析为“\”,{char=\C} 解析为大写 C。如果没有转义字符,{char=\} 将是无效表达式,{char=C} 将解释为小写 c。 请确保在元数据格式中区分大小写的所有大写字母之前使用反斜杠转义字符。

示例表达式

下表提供了查询语言分析程序对其解释的一些示例表达式和说明。

表达式 说明
ifd/xmp/exif:Author 对应于以下导航路径:IFD 块 -> XMP 块 -> “Exif” 架构中的“Author”属性。
/[1]ifd/[0]xmp/exif:Author 与此表中的第一项相同,只是 [#] 前缀描述了在发生名称冲突时要导航的项。
/ifd/{ushort=700}/Author 与表中的第一项相同,只不过它使用数据表达式来引用 XMP 块而不是块名称“xmp” (XMP 块嵌入在无符号短标记标识符 700) 下。 此外,“Author”属性不指定架构。 查询分析程序将尝试在所有架构中匹配 属性,并返回第一个匹配项。
/ifd/xmp 提供元数据块的导航路径。 如果找到块,则返回新的元数据读取器/编写器。
/[*]tEXt/Keyword 获取或设置 PNG 区块的 Keyword 属性。 由于 PNG 元数据规范允许特定类型的多个区块,因此 [*] 表示法使用适当的属性获取/设置数据 PNG 区块。 根据 PNG 规范,不能有两个区块具有相同的属性。

 

每个元数据块也由元数据 GUID 唯一标识,该 GUID 可用于代替友好的块名称。 可以使用以下语法代替提供块名称:“/{guid=GUID}/[n]{guid=GUID}/schema:tagidentifier”

下表提供了一些无效示例以及拒绝这些示例的原因。

表达式无效 拒绝说明
/ifd/[0][2]exif/ 拒绝,因为不支持多维数组索引。
/ifd/{ushort=1}/{ushort=2} 拒绝,除非 IFD 具有 tagID=1,这是一个元数据处理程序,其中包含具有 tagID=2 的元数据项。
/{ushort=1} 如果查询处理相对于元数据层次结构的顶层,则被拒绝。 这是因为顶级仅包含元数据块,而不包含数据项。

 

照片元数据策略表达式

如前所述,完全限定的查询表达式以斜杠 (/) 开头。 不以斜杠开头的表达式将计算为策略表达式。 使用策略表达式可以查询与图像相关的 Windows Shell 属性的照片元数据。 在本文档前面的“数据选择”部分中,使用了表达式“/xmp/xmp:Rating”来访问 XMP 分级属性。 还可以使用以下策略表达式查询此属性:

  • System.SimpleRating

若要从 MicrosoftPhoto 架构访问 rating 属性,可以使用以下查询表达式:

  • System.Rating

照片元数据策略表达式的行为与完全限定的元数据查询在一些值得注意的方式上不同。

首先,在使用策略表达式访问元数据时,如果同一属性在多个元数据块中可用,WIC 将执行仲裁和冲突解决。 例如,MicrosoftPhoto 和 XMP 分级值都存储在 App1/IFD 块和 XMP 块中。 照片元数据策略确定读取元数据时为其返回块值的优先级。 编写元数据时,照片元数据策略可确保不同块中的相同属性保持一致。 如果使用“/xmp/xmp:Rating”等元数据查询,则负责在各种元数据位置之间进行仲裁。

注意

有关支持的策略表达式及其映射策略的列表,请参阅 照片元数据策略 主题。

 

其次,照片元数据策略表达式独立于图像格式,而完全限定的元数据查询则无关。 例如,“/xmp/xmp:Rating”查询特定于 JPEG 格式。 TIFF 图像也支持 XMP 元数据,但与 JPEG 相比,其存储方式不同,因此 TIFF 查询为“/ifd/xmp/xmp:Rating”。 但是,在这两种情况下,策略表达式均为“System.SimpleRating”。

与完全限定的元数据查询相比,照片元数据策略表达式提供了更高级别的抽象和简单性,因此在不需要低级别元数据访问的情况下,应优先使用。 但是,策略表达式仅提供对一组有限的图像元数据的访问,而元数据查询语言提供对图像文件中存储的几乎所有元数据的访问。

元数据查询语言摘要

下表是 WIC 元数据查询语言的正式定义。 每个语法符号表示由其他符号组成的表达式。 表达式可以是另一个符号,也可以是用垂直条分隔的其他符号的序列 (|) ,指示“或”选项。 右侧的整个表达式可以替换左侧的指定符号。

符号 表达式
<路径> <name> |“/” <属性路径>
<属性路径> <元数据项> | <属性路径> “/” <属性路径>
<元数据项> <索引名称> | <项目名称> | <架构名称> “:” <项名称>
<架构名称> <项目名称>
<项目名称> <元数据项> | <索引项><索引>
<索引项> <item> | <隐含元数据><项>
<隐含元数据> “<'<name>'>”
<item> <name> | &lt;index><数据> | <数据>
data<> “{” <数据类型> “=” <值> “}”
&lt;index> “[”<数字> | <> star“]”
<数据类型> “char”|“uchar” |“short”|“ushort”|“long”|“ulong”|“int” |“uint”|“longlong”|“ulonglong”|“float”|“double”|“str”|“wstr” |“guid”|“bool”
<数据值> <number> | <name> | <Guid>
<星号键> '*'
<数字> 数字
name<> string
<guid> guid

 

概念性

Windows 映像组件概述

WIC 元数据概述

读取和写入图像元数据概述

元数据扩展性概述

操作说明:使用元数据重新编码 JPEG 图像