WIC 元数据概述

本主题介绍 Windows 映像组件 (WIC) 提供的映像元数据支持。 其中介绍了如何读取和写入图像元数据、元数据查询语言和元数据处理程序扩展性。

图像元数据是嵌入在图像文件中的数据,它提供有关图像的其他信息,例如用于捕获图像的设备或图像的尺寸。 尽管它包含在图像文件本身中,但此元数据不是呈现数据的一部分。 WIC 提供接口,使你能够读取和写入多种常见元数据格式的元数据,包括可扩展元数据平台 (XMP) 、可交换图像文件 (EXIF) 和 Png 文本数据 (tEXt) 。

本主题包含以下各节:

先决条件

若要了解本主题,应熟悉 WIC 编码器和解码器接口及其相关的组件对象模型 (COM) 组件,如 Windows 映像组件概述中所述。 它还有助于大致熟悉目前使用的一些图像元数据格式。

简介

元数据提供有关图像的扩展信息。 此信息可通过多种方式使用。 图像可能包含元数据,例如说明、分级、类别标记和版权信息。 通过访问元数据,可以更轻松地执行资产管理、文件位置或确定版权信息等任务。 例如,Windows Vista 中的 Windows 照片库使你能够向图像添加说明和类别标记。 这样可以更好地发现图像,并方便地对图像进行分类。 使用 WIC API 和常见元数据格式,应用程序可以轻松地在图像中写入或读取此类元数据。

下图演示了包含嵌入元数据块和元数据项的 JPEG 文件的内容。

带有评级元数据的 jpeg 图像

在此示例图像中,元数据嵌入在图像帧内的图像文件中。 JPEG 格式不支持多个图像帧,因此元数据在概念上附加到此单个帧。 支持多个帧的格式(如 TIFF)可能具有附加到每个图像帧的元数据,如下图所示。 尽管目前并不常见且不受本机图像编解码器支持,但某些图像格式可能还支持图像帧外部的元数据。 WIC 足够灵活,可以处理帧级元数据和图像单个帧之外的元数据。

读取图像元数据

WIC API 提供 COM 组件,使应用程序能够轻松地读取和写入图像元数据。

读取元数据的主要方法是使用元数据查询读取器 (IWICMetadataQueryReader) 来访问特定的元数据项。 元数据查询读取器组件由编解码器实现,可以在解码器级别或通过单个图像帧(这是更常见的方法)进行访问。 以下代码演示如何使用查询读取器的 GetMetadataQueryReader 方法访问单个帧的查询读取器。

// Get the query reader
if (SUCCEEDED(hr))
{
    hr = pFrameDecode->GetMetadataQueryReader(&pQueryReader);
}

查询读取器提供获取特定元数据相关信息的方法,以及指定要检索的元数据项的方法。 以下代码使用查询表达式请求 App1 嵌套图像文件目录中的特定元数据项 (IFD) 块。 这是通过使用查询读取器的 GetMetadataByName 方法完成的。 以下代码演示如何使用查询读取器获取 MicrosoftPhoto 分级值。

PROPVARIANT value;
PropVariantInit(&value);

LPCWSTR pwzRatingQuery = L"/app1/ifd/{ushort=18249}";

if (SUCCEEDED(hr))
{
    hr = pQueryReader->GetMetadataByName(pwzRatingQuery, &value);
}

上述示例中的 pwzRatingQuery 变量是用于访问元数据项 MicrosoftPhoto 分级的查询字符串。 此字符串是使用元数据查询语言创建的。 若要创建此字符串,需要了解元数据格式和元数据查询语言才能检索单个元数据项。 有关元数据查询语言的详细信息,请参阅 元数据查询语言概述

在后台,查询读取器使用元数据读取器 (IWICMetadataReader) 来访问查询表达式描述的元数据。 除了使用查询读取器之外,还可以直接访问元数据读取器来读取元数据。 可以通过 (IWICMetadataBlockReader) 接口查询块读取器,从解码器或单个帧获取元数据读取器。

写入图像元数据

编写元数据的过程与读取方式类似,只不过使用元数据查询编写器 (IWICMetadataQueryWriter) 。 查询编写器接口由图像编码器实现,并且与在查询读取器中一样,元数据可在编码器和单个帧上访问, (具体取决于图像格式支持) 。

以下代码演示如何从编码器帧获取查询编写器并删除之前读取的评级值。

// Get the frame's query writer
if (SUCCEEDED(hr))
{
    hr = pFrameEncode->GetMetadataQueryWriter(&pFrameQWriter);
}

if (SUCCEEDED(hr))
{
    hr = pFrameQWriter->RemoveMetadataByName(L"/app1/ifd/{ushort=18249}");
}

写入元数据的另一种方法是快速更新元数据。 快速元数据编码是一种无需重新编码图像文件即可写入图像元数据的方法。 这是通过将新的元数据信息写入元数据格式的填充区域来完成的。 基于映像解码器从组件工厂获取快速元数据编码器 (IWICFastMetadataEncoder) 。 然后,快速元数据编码器获取用于写入元数据的查询编写器。 最后,快速编码器提交更改。

以下代码演示如何获取快速元数据编码器并使用它来编写 MicrosoftRating 值。

if (SUCCEEDED(hr))
{
    IWICFastMetadataEncoder *pFME = NULL;
    IWICMetadataQueryWriter *pFMEQW = NULL;

    hr = pFactory->CreateFastMetadataEncoderFromFrameDecode(
        pFrameDecode,
        &pFME);

    if (SUCCEEDED(hr))
    {
        hr = pFME->GetMetadataQueryWriter(&pFMEQW);
    }

    if (SUCCEEDED(hr))
    {
        // Add additional metadata
        PROPVARIANT value;

        PropVariantInit(&value);

        value.vt = VT_UI4;
        value.uiVal = 99;
        hr = pFMEQW->SetMetadataByName(L"/app1/ifd/{ushort=18249}", &value);

        PropVariantClear(&value);
    }

    if (SUCCEEDED(hr))
    {
        hr = pFME->Commit();
    }
}

并非所有元数据格式都支持快速元数据。 若要查看哪些本机支持的格式支持快速元数据编码,请参阅本文档后面 支持的元数据格式 部分中的表。

在后台,查询编写器使用元数据编写器 (IWICMetadataWriter) 编写查询表达式描述的元数据。 除了使用查询读取器,还可以直接访问元数据编写器来写入元数据。 可以使用 IWICMetadataBlockWriter) 接口查询块编写器,从解码器或单个帧获取元数据 (编写器。

元数据可扩展性

如前所述,WIC 提供了多个元数据处理程序,用于读取和写入常见元数据格式的元数据。 但是,某些元数据格式本身不受支持。 因此,WIC 提供了用于创建其他元数据处理程序的 API,这些处理程序可将元数据支持扩展到其他格式。

若要完全支持其他元数据格式,必须开发两种类型的处理程序 : 用于读取元数据的元数据读取器和用于写入元数据的元数据编写器。 尽管这两个处理程序通常是针对特定格式成对实现的,但这不是必需的。 在某些情况下,可能只需要读取功能或仅需要写入功能。

有关使用 WIC API 的元数据扩展性的详细信息,请参阅 元数据扩展性概述

支持的元数据格式

WIC 支持多种常见的元数据格式。 下表列出了支持的元数据格式、其版本、支持元数据格式的图像格式,以及元数据格式是否支持快速元数据编码。 有关快速元数据编码的详细信息,请参阅本文档前面的 编写图像元数据 部分。

支持的元数据格式 元数据规范版本 图像格式支持 支持快速元数据编码
App0 JFIF 1.02 JPEG
App1 JFIF 1.02 JPEG、TIFF
App13 未知 JPEG、TIFF
IFD TIFF 6.0 JPEG、TIFF
Irb 未知 JPEG、TIFF
Exif Exif 2.2 JPEG、TIFF
XMP XMP 1.0 (2005 年 9 月) JPEG、TIFF
GPS Exif 2.2 JPEG、TIFF
IPTC IPTC 4.0 JPEG、TIFF
文本 PNG 1.2 PNG

 

注意

IPTC 仅当块大小增大时才支持 FME,因为 IPTC 不支持填充。

 

元数据组件摘要

下表描述了支持元数据的 WIC 接口及其相应的组件。 这些组件提供对图像元数据的访问。 有关这些组件的详细信息,请参阅 Windows 映像组件概述

组件 说明
位图解码器 (IWICBitmapDecoder)
  • 读取图像流并生成一个可用位图源。 与容器格式(例如标记图像文件格式 (TIFF) 或联合摄影专家组 (JPEG) 相关联。
  • 实现 IWICMetadataBlockReader 接口,以枚举解码器数据流中不在帧中的所有元数据块。
  • 公开查询读取器以读取与不在帧内的图像关联的元数据。
位图帧解码 (IWICBitmapFrameDecode)
  • 从解码器保留的图像流访问单个帧。
  • 实现 IWICMetadataBlockReader 接口,以枚举帧数据流中的所有元数据块。
  • 使用查询表达式公开查询读取器以读取与帧关联的元数据。
位图编码器 (IWICBitmapEncoder)
  • 将位图源写入图像流。 与容器格式(如 TIFF 或 JPEG)关联。
  • 实现 IWICMetadataBlockWriter 接口,以生成要写入编码器数据流的元数据块列表。
  • 公开查询编写器,以使用查询表达式编写与图像关联的元数据。
Bitma 帧编码 (IWICBitmapFrameEncode)
  • 创建一个帧,该帧将编码为编码器持有的流。
  • 实现 IWICMetadataBlockWriter 接口,以生成要写入帧数据流的元数据块列表。
  • 公开查询编写器,以使用查询表达式编写与帧关联的元数据。

 

下表介绍了 WIC 元数据组件。 这些组件使你能够读取和写入由上表中列出的组件公开的图像中的元数据。

组件 说明
元数据查询读取器 (IWICMetadataQueryReader)
  • 获取查询字符串并导航基础元数据层次结构以获取元数据。
元数据查询编写器 (IWICMetadataQueryWriter)
  • 获取查询字符串并导航基础元数据层次结构以获取、设置和删除元数据。
元数据块读取器 (IWICMetadataBlockReader)
  • 管理元数据层次结构顶部的 IWICMetadataReader 对象的只读集合,并启用所有元数据块的枚举。
  • 由位图解码器和解码的位图帧实现。
  • 由第三方组件开发人员为自定义编解码器实现。
元数据块编写器 (IWICMetadataBlockWriter)
  • 管理元数据层次结构顶部的 IWICMetadataWriter 对象的读取和写入集合。
  • 由位图编码器和位图帧编码实现。
  • 由第三方组件开发人员为自定义编解码器实现。
元数据读取器 (IWICMetadataReader)
  • 分析元数据流并管理元数据项的只读集合。 与 EXIF、IFD 和 XMP 等元数据格式关联。
  • 充当字典,在给定格式和 ID 对时返回值。
  • 由第三方组件开发人员为自定义元数据类型实现。
元数据编写器 (IWICMetadataWriter)
  • 分析和序列化元数据流,并管理元数据项的读/写集合。
  • 由第三方组件开发人员为自定义元数据类型实现。
快速元数据编码器IWICFastMetadataEncoder
  • 公开用于在元数据层次结构上写入的语义,该层次结构将就地更新元数据,而无需重新编码图像。

 

概念性

Windows 映像组件概述

元数据查询语言概述

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

元数据扩展性概述

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