前言:
学习笔记,随时更新。如有谬误,欢迎指正。
说明:
- 红色字体为较为重要部分。
- 绿色字体为个人理解部分。
原文链接:https://learn.microsoft.com/en-us/windows/win32/gdi/metafiles
10 图元文件
- 图元文件是以设备无关的格式存储图片的结构的集合。设备独立性是将元文件与位图区分开来的一个特性。与位图不同,图元文件保证了设备的独立性。然而,图元文件有一个缺点,它们通常比位图绘制得慢。因此,如果应用程序需要快速绘图并且设备无关性不是问题,则应该使用位图而不是图元文件。
10.1 关于图元文件
-
在内部,图元文件是称为“图元文件记录”的可变长度结构数组。图元文件中的第一个记录指定一般信息,例如创建图片的设备的分辨率、图片的尺寸等等。其余的记录构成了任何图元文件的主体,它们对应于绘制图像所需的 GDI 函数。在创建了一个特殊的图元文件设备上下文之后,这些记录存储在图元文件中。然后,这个图元文件设备上下文用于创建图片所需的所有绘制操作。当系统处理与图元文件 DC 关联的 GDI 函数时,它将函数转换为适当的数据,并将该数据存储在附加到图元文件的记录中。
图片完成后,最后一条记录存储在图元文件中,可以通过以下方式将图元文件传递给另一个应用程序:
- 使用剪贴板
- 将其嵌入另一个文件中
- 将其存储在磁盘上
- 反复播放
-
当图元文件的记录被转换为设备命令并由适当的设备处理时,图元文件就会被播放。
10.1.1 增强格式的图元文件
-
增强格式图元文件包含以下元素:
- 头(信息)
- GDI 对象的句柄表
- 私有调色板
- 图元文件记录数组
-
增强的图元文件提供了真正的设备独立性。可以将存储在增强图元文件中的图片视为在特定时刻拍摄的视频显示的“快照”。无论“快照”出现在打印机、绘图仪、桌面或任何应用程序的客户端区域的哪个位置,它都会保持其尺寸。
-
可以使用增强的图元文件来存储通过使用 GDI 函数(包括新的路径和转换函数)创建的图片。由于增强的图元文件格式是标准化的,因此以这种格式存储的图片可以从一个应用程序复制到另一个应用程序;而且,由于图片是真正独立于设备的,因此它们可以保证在任何输出设备上保持其形状和比例。
10.1.1.1 增强的图元文件记录
1.增强图元文件是一个记录数组。图元文件记录是一个可变长度的 ENHMETARECORD 结构。在每个增强图元文件记录的开头是一个 EMR 结构,它包含两个成员。第一个成员 iType 标识记录的类型,即记录中包含其参数的 GDI 函数。因为结构体的长度是可变的,所以另一个成员 nSize 包含了记录的大小。紧跟在 nSize 成员之后的是 GDI 函数的剩余参数(如果有的话)。结构的其余部分包含依赖于记录类型的附加数据。
-
增强图元文件中的第一个记录始终是 ENHMETAHEADER 结构,它是增强的图元文件头。头指定了以下信息:
- 图元文件的大小,字节为单位。
- 画框的尺寸,以设备为单位。
- 画框的尺寸,以 0.01 毫米为单位。
- 图元文件中的记录数。
- 可选文本描述的偏移量。
- 可选调色板的大小。
- 原始设备的分辨率,以像素为单位。
- 原始设备的分辨率,以毫米为单位。
-
可选的文本描述可以跟在标题记录后面。文字描述描述了图片和作者的名字。可选调色板指定用于创建增强元文件的颜色。其余的记录标识用于创建图片的 GDI 函数。
-
有关其他记录类型的列表,请参阅图元文件结构体。
10.1.1.2 增强图元文件的创建
-
可以使用 CreateEnhMetaFile 函数创建增强的图元文件,并提供适当的参数。系统使用这些参数来维护图片尺寸,确定图元文件是应该存储在磁盘上还是内存中,等等。
-
为了维护跨输出设备的图片尺寸, CreateEnhMetaFile 需要参考设备的分辨率。这个参考设备是图片第一次出现的设备,参考 DC 是与参考设备相关联的设备上下文。在调用 CreateEnhMetaFile 函数时,必须提供标识此 DC 的句柄。可以通过调用 GetDC 或 CreateDC 函数来获得这个句柄。还可以指定 NULL 作为句柄,以使用当前显示设备作为参考设备。
-
大多数应用程序永久存储图片,因此创建一个存储在磁盘上的增强图元文件;然而,在某些情况下,这是不必要的。例如,提供图表绘制功能的文字处理应用程序可以将用户定义的图表作为增强图元文件存储在内存中,然后将增强图元文件位从内存复制到用户的文档文件中。需要永久存储在磁盘上的图元文件的应用程序在调用 CreateEnhMetaFile 时必须提供文件名。如果不提供文件名,系统将自动将图元文件视为临时文件并将其存储在内存中。
-
可以向包含有关图片和作者信息的图元文件添加可选的文本描述。应用程序可以在“文件打开”对话框中显示这些字符串,以向用户提供有关图元文件内容的信息,这将有助于选择适当的文件。如果应用程序包含文本描述,则在调用 CreateEnhMetaFile 时必须提供指向该字符串的指针。
-
当 CreateEnhMetaFile 成功时,它返回一个识别特殊图元文件设备上下文的句柄。图元文件设备上下文是唯一的,因为它与文件关联,而不是与输出设备关联。当系统处理接收到图元文件设备上下文句柄的 GDI 函数时,它将 GDI 函数转换为增强图元文件记录,并将该记录附加到增强图元文件的末尾。
-
在图片完成并将最后一条记录追加到增强的图元文件之后,应用程序可以通过调用 CloseEnhMetaFile 函数关闭该文件。此函数关闭并删除特殊图元文件设备上下文,并返回标识增强图元文件的句柄。
-
要删除增强格式图元文件或增强格式图元文件句柄,请调用 DeleteEnhMetaFile 函数。
10.1.1.3 增强的图元文件操作
10.1.1.3.1 显示存储在增强型图元文件中的图片
- 可以使用 PlayEnhMetaFile 函数显示存储在增强图元文件中的图片。将函数句柄传递给增强的图元文件,而不关心增强的图元文件记录的格式。但是,有时需要枚举增强图元文件中的记录,以搜索特定的 GDI 函数并以某种方式修改函数的参数。为此,可以使用 EnumEnhMetaFile 并提供一个回调函数 EnhMetaFileProc 来处理增强的图元文件记录。要修改增强型图元文件记录的参数,必须知道记录内参数的格式。
10.1.1.3.2 创建增强型图元文件的副本
-
一些应用程序在允许用户更改原始文件之前创建文件的临时备份副本。应用程序可以调用 CopyEnhMetaFile 函数,提供标识增强图元文件的句柄,并提供指向新文件名的指针,从而创建增强图元文件的备份副本。
-
要创建基于内存的增强格式图元文件,请调用 SetEnhMetaFileBits 函数。
10.1.1.3.3 编辑增强型图元文件
- 大多数绘图、插图和计算机辅助设计( CAD )应用程序都需要一种编辑存储在增强图元文件中的图片的方法。尽管编辑增强型图元文件是一项复杂的任务,但是可以将 EnumEnhMetaFile 函数与其他函数结合使用,在应用程序中提供这种功能。 EnumEnhMetaFile 函数及其关联的回调函数 EnhMetaFileProc 使应用程序能够在增强的图元文件中处理单个记录。
10.1.1.3.4 查询存储在增强型图元文件中的可选说明
- 某些应用程序在“打开”对话框中显示增强图元文件的文本描述和相应的文件名。可以通过使用 GetEnhMetaFileHeader 函数查询图元文件头并检查其成员之一来确定该字符串是否存在于增强的图元文件中。如果字符串存在,应用程序通过调用 GetEnhMetaFileDescription 函数来获取它。
10.1.1.3.5 查询增强型图元文件的二进制版本
- 可以通过调用 GetEnhMetaFileBits 函数来查询图元文件的内容;但是,在查询内容之前,必须指定文件的大小。要获取大小,可以使用 GetEnhMetaFileHeader 函数并检查适当的成员。
10.1.1.3.6 枚举可选调色板中的颜色
- 为了在不同的输出设备上显示图片时获得一致的颜色,可以调用 CreatePalette 函数并在增强的图元文件中存储逻辑调色板。显示存储在增强图元文件中的图片的应用程序会查询这个调色板,并在显示图片之前调用 RealizePalette 函数。要确定调色板是否存储在增强的图元文件中,请查询图元文件头并检查适当的成员。如果存在一个调色板,可以调用 GetEnhMetaFilePaletteEntries 函数来查询逻辑调色板。
10.1.2 Windows 格式图元文件
-
Microsoft Windows 格式的图元文件功能有限,应该很少使用。支持 Windows 格式函数是为了保持与为 16 位 Windows 编写的应用程序运行的向后兼容性。正常情况下应该使用增强格式函数。
-
该格式的限制和 Windows 格式图元文件的函数见 Windows 格式图元文件。
10.2 使用图元文件
10.2.1 创建增强型图元文件
- 有关详细信息,请参阅创建增强型图元文件。
10.2.2 显示图片并将其存储在增强型图元文件中
- 有关详细信息,请参阅显示图片并将其存储在增强型图元文件中。
10.2.3 打开增强型图元文件并显示其内容
- 有关详细信息,请参阅打开增强型图元文件并显示其内容。
10.2.4 编辑增强型图元文件
- 有关详细信息,请参阅编辑增强型图元文件。
10.3 图元文件参考
10.3.1 图元文件函数
- 有关详细信息,请参阅图元文件函数。
10.3.2 图元文件结构体
- 有关详细信息,请参阅图元文件结构体。