人员 标记概述
本主题介绍新的可扩展元数据平台 (XMP) 架构,以及启用数字照片中个人标记的 Windows 7 照片属性 System.Photo.PeopleNames 。 本主题还讨论如何使用 Windows 图像处理组件 (WIC) API 读取和写入人员标记所需的元数据。
本主题包含以下各节:
若要了解本主题,应熟悉 WIC 解码器接口及其相关的组件对象模型 (COM) 组件,如 Windows 映像组件概述中所述。 它还有助于大致熟悉图像元数据,尤其是 XMP。
Microsoft 创建了一个新的 XMP 架构,用于在数字图像中标记人员。 此架构使应用程序能够将图像中个人的姓名和位置存储为映像中的元数据。 除了新架构之外,Windows 7 中还提供了新的照片属性 System.Photo.PeopleNames 。 此新属性使应用程序能够读取存储在图像元数据中的个人姓名。 WIC 利用这些新功能,使应用程序能够轻松地读取和写入数字照片中标记元数据的人员。
WIC 为应用程序开发人员提供 COM 组件,用于读取图像数据和图像元数据。 对于读取和写入元数据(例如新的人员标记功能),WIC 提供 IWICMetadataQueryReader 和 IWICMetadataQueryWriter 接口。 这些接口使应用程序能够使用 元数据查询语言 将元数据写入图像的各个帧。 以下部分演示如何使用 WIC 查询读取器和编写器将人员标记元数据读取和写入图像的元数据。
人员标记功能的一部分是,只需获取图像中标记的人员姓名的列表即可。 System.Photo.PeopleNames 和 WIC 的元数据处理程序支持此功能的这一部分。 IWICMetadataQueryReader 接口与 System.Photo.PeopleNames 属性一起用于读取图像中标识并存储在图像元数据中的人员的姓名。
下面的代码示例演示从图像帧获取的查询读取器,用于查询图像元数据以获取 System.Photo.PeopleNames 属性的标记名称。
// Not shown: image decoding, retrieving an image frame.
...
PROPVARIANT value;
IWICMetadataQueryReader *pQueryReader = NULL;
...
// Get the query reader.
if (SUCCEEDED(hr))
{
hr = pFrameDecode->GetMetadataQueryReader(&pQueryReader);
}
// Query for the System.Photo.PeopleNames property.
if (SUCCEEDED(hr))
{
// Get the property metadata by property name.
hr = pQueryReader->GetMetadataByName(L"System.Photo.PeopleNames", &value);
}
查询表达式“System.Photo.PeopleNames”查询属性的帧。 如果人员标记元数据存在并且包含人员的姓名, 则 PROPVARIANT 值将设置为 VT_LPWSTR 并且数据值将包含标记姓名的列表。 有关读取图像元数据的详细信息,请参阅 读取和写入图像元数据概述。
仅当图像实际包含人员标记元数据时,查询人员姓名标记才有用。 为此,应用程序必须首先编写它。 若要编写人员姓名元数据,请使用 IWICMetadataQueryWriter 和元数据的显式 XMP 路径。 下面的代码示例演示如何使用查询编写器将名称写入查询路径。
// Not shown: image encoding, retrieving/creating the image frame,
// creating the IWICImagingFactory
...
IWICImagingFactory *pFactory = NULL;
IWICMetadataQueryWriter *pQueryWriter = NULL;
...
// Get the query writer from the image frame.
if (SUCCEEDED(hr))
{
hr = pFrameEncode->GetMetadataQueryWriter(&pQueryWriter);
}
// A query writer specifically for this person's XMP struct
IWICMetadataQueryWriter *pXMPStructQueryWriter = NULL;
// Create a query writer specifically for an XMP Struct
hr = pFactory->CreateQueryWriter(
GUID_MetadataFormatXMPStruct,
NULL,
&pXMPStructQueryWriter
);
// Create a variant representing the structure created above
PROPVARIANT xmpStruct;
PropVariantInit(&xmpStruct);
// VT_UNKNOWN indicates that we're setting a COM object, in this case a XMPStruct
// which will hold the name and rectangle
xmpStruct.vt = VT_UNKNOWN;
xmpStruct.punkVal = pXMPStructQueryWriter;
if(SUCCEEDED(hr))
{
// WIC will automatically create the xmp base, the RegionInfo struct, and the Regions
// bag (an unordered array) but structs within that bag need to be explicitly created.
// The {ulong=0} in the query means to insert the new struct at the start of the bag,
// {} could also be used to insert at the end of the bag.
hr = pQueryWriter->SetMetadataByName(
L"/xmp/<xmpstruct>MP:RegionInfo/<xmpbag>MPRI:Regions/{ulong=0}",
&xmpStruct
);
}
// Set up the PROPVARIANT with the name information
PROPVARIANT personName;
PropVariantInit(&personName);
personName.vt = VT_LPWSTR;
personName.pwszVal = L"John Doe";
if(SUCCEEDED(hr))
{
// Set the name metadata
hr = pQueryWriter->SetMetadataByName(
L"/xmp/MP:RegionInfo/MPRI:Regions/{ulong=0}/MPReg:PersonDisplayName",
&personName
);
}
请注意构造 XMP 结构并在 下 MPRI:Regions/{ulong=0}
设置它的步骤。 如果不执行此步骤,WIC 将无法确定稍后的放置 PersonDisplayName
位置。 另请注意,使用显式查询路径而不是 System.Photo.PeopleNames,后者的元数据策略不支持写入元数据。
但是,人员的名称只是人员标记功能的一部分。 除了在元数据中存储人员的姓名外,该架构还支持区域信息,该信息标识特定区域 (一个矩形) 人员显示在图像中。
矩形信息由四个逗号分隔的十进制值表示,例如“0.25, 0.25, 0.25, 0.25”。 前两个值指定左上角坐标;最后两个指定矩形的高度和宽度。 出于定义人员矩形的目的,图像的尺寸规范化为 1,这意味着在“0.25, 0.25, 0.25, 0.25”示例中,矩形从顶部开始距离的 1/4, 到图像左侧的距离的 1/4。 矩形的高度和宽度都是其各自图像尺寸大小的 1/4。
标识个人的矩形信息以相同结构中写入人员姓名的方式写入。 若要写入矩形元数据,请使用 IWICMetadataQueryWriter 和元数据的显式 XMP 路径。 下面的代码示例继续前面的示例,并将表示“John Doe”的矩形添加到图像的元数据中。 请注意,它使用相同的 {ulong=0}
索引将此矩形与“John Doe”相关联。
// Set up the PROPVARIANT with the rectangle information
PROPVARIANT rectangle;
PropVariantInit(&rectangle);
rectangle.vt = VT_LPWSTR;
rectangle.pwszVal = L"0.0,0.0,0.25,0.25";
if(SUCCEEDED(hr))
{
// Set the rectangle metadata
hr = pQueryWriter->SetMetadataByName(
L"/xmp/MP:RegionInfo/MPRI:Regions/{ulong=0}/MPReg:Rectangle",
&rectangle
);
}
用于标记人员的 Microsoft XMP 架构定义了一组用于在数码照片中标记个人的属性。
以下部分提供人员标记所需的架构定义。 架构定义尽可能使用 Adobe 的可扩展元数据平台 (XMP) 规范提供的约定。 本主题中的架构定义显示标识架构和首选架构命名空间前缀的 XML 命名空间统一资源标识符 (URI) ,后跟一个表,其中列出了为架构定义的所有属性。 每个表都具有以下列:
属性 - 属性的名称,包括首选命名空间前缀。
值类型 - 属性的值类型。 人员标记支持架构尽可能使用 XMP 值类型,包括日期和文本。 数组类型前面是容器类型:
alt
、bag
或seq
。类别 - 架构属性为内部或外部:
内部元数据必须由应用程序设置。
外部元数据必须由用户设置,并且独立于文档的内容。
Description - 属性的说明。
Microsoft Photo 1.2 架构为图像区域提供一组属性。
- 架构命名空间 URI 为
https://ns.microsoft.com/photo/1.2/
。 - 首选架构命名空间前缀为
MP
。
属性 | 值类型 | 类别 | 说明 |
---|---|---|---|
MP:RegionInfo | RegionInfo | 内部 | required :存储人员标记元数据的根。 请参阅下面的 Microsoft Photo RegionInfo 架构部分。 |
Microsoft Photo RegionInfo 1.2 架构为区域信息提供一组属性。
- 架构命名空间 URI 为
https://ns.microsoft.com/photo/1.2/t/RegionInfo#
。 - 首选架构命名空间前缀为
MPRI
。
属性 | 值类型 | 类别 | 说明 |
---|---|---|---|
MPRI:DateRegionsValid | 日期 | 外部 | 可选 :创建最后一个区域的日期。 |
MPRI:Regions | 包区域 | 外部 | required :存储标记区域的人员。 请参阅下面的 Microsoft 照片区域架构部分。 |
Microsoft 照片区域 1.2 架构为图像区域提供一组属性。
- 架构命名空间 URI 为
https://ns.microsoft.com/photo/1.2/t/Region#
。 - 首选架构命名空间前缀为
MPReg
。
MPReg:属性 | 值类型 | 类别 | 说明 |
---|---|---|---|
MPReg:PersonDisplayName | 文本 | 外部 | 必需 :将人员的姓名存储在给定矩形中。 |
MPReg:Rectangle | 文本 | 外部 | 可选 :存储标识照片中人物的矩形。 矩形存储为四个逗号分隔的十进制值。 前两个值指定左上角坐标;最后两个指定矩形的高度和宽度。 小数点值必须规范化为 1。 |
MPReg:PersonEmailDigest | 文本 | 外部 | 可选 :存储用户的实时电子邮件地址的 SHA-1 加密邮件哈希。 |
MPReg:PersonLiveIdCID | 文本 | 外部 | 可选 :存储人员 Live CID 的带符号十进制表示形式,这是一个公开标识 Live 标识的 64 位整数。 |
下面是用于人员标记的 XMP 元数据的表示形式。
<rdf:Description rdf:about="" xmlns:MP="https://ns.microsoft.com/photo/1.2/">
<MP:RegionInfo>
<rdf:Description xmlns:MPRI="https://ns.microsoft.com/photo/1.2/t/RegionInfo#">
<MPRI:Regions>
<rdf:Bag>
<rdf:li>
<rdf:Description xmlns:MPReg="https://ns.microsoft.com/photo/1.2/t/Region#">
<MPReg:Rectangle>0.790650, 0.441734, 0.209350, 0.279133
</MPReg:Rectangle>
<MPReg:PersonDisplayName>John Doe</MPReg:PersonDisplayName>
<MPReg:PersonEmailDigest>2FD4E1C67A2D28FCED849EE1BB76E7391B93EB13</MPReg:PersonEmailDigest>
<MPReg:PersonLiveIdCID>1234567890123456789</MPReg:PersonLiveIdCID>
</rdf:Description>
</rdf:li>
<rdf:li>
<rdf:Description xmlns:MPReg="https://ns.microsoft.com/photo/1.2/t/Region#">
<MPReg:Rectangle>0.222656, 0.302083, 0.378906, 0.505208</MPReg:Rectangle>
<MPReg:PersonDisplayName>Jane Doe</MPReg:PersonDisplayName>
</rdf:Description>
</rdf:li>
<!-- Addition Regions --> ...
<rdf:li>...
</rdf:li>
</rdf:Bag>
</MPRI:Regions> </rdf:Description> </MP:RegionInfo> </rdf:Description>