文档元数据和导航

Posted ball球

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了文档元数据和导航相关的知识,希望对你有一定的参考价值。

本文是对PDF Explained(by John Whitington)第七章《 Document Metadata and Navigation》的摘要式翻译,并加入了一些自己的理解。

本章我们讨论四个辅助数据,这些数据并不影响PDF的显示。

  • 定位(Destinations):定义文件中位置的数据结构。它们可用于指定书签或超链接指向的位置。书签就是文档的目录。
  • XML元数据: 流数据,包含了特定格式的XML文件,一些与文档信息字典相同的元数据,以及其他字段。
  • 文件附件:允许像电子邮件附件那将将整个文件封装在文档中。
  • 注释:允许文本或图形独立与主页面内容,显示在PDF页面之。上超链接是一种特殊的注释,它允许用户点击跳转到文件中的任意位置。

书签与定位(Destinations)

文档书签(也被称为文档大纲)是一棵由条目组成的树(条目通常是章节或段落的标题),点击这些条目可以跳转到文档中相应的位置。每个条目由文本和用来描述跳转链接的定位构成。

定位(Destinations)

定位定义了PDF文档中的一个位置,由三部分组成,包括页码,页内位置以及显示缩放比率。定位可以被精确的定义,也可以通过名称引用进行定义。书签通常显示在文档旁边。

定位是使用数组对象定义的,内容取决于定位的类型。其语法如下表所示:

数组描述
[page /Fit]显示page指定的整个页面,页面缩放到刚好合适当前窗口大小。
[page /FitH top]显示page页,垂直坐标top指定距窗口的上边缘的位置,page水平缩放至适合窗口的宽度。
[page /FitV left]显示page页,水平坐标left指定距窗口左边缘的位置,page垂直缩放至适合窗口的高度。
[page /XYZ left top zoom]显示page页,left,top用于指定窗口的左上角,页面通过zoom因子进行缩放。任何参数为null时,表示该参数保持不变。
[page /FitR left bottom right top]在由left bottom right top指定的矩形区域内显示整个页面。
[page /FitB]像 /Fit那样显示page页,使用页面内容的边界框而非裁剪框。
[page /FitBH top]像 /FitH那样显示page页,使用页面内容的边界框而非裁剪框。
[page /FitBV left]像/FitV那那样显示page页,使用页面内容的边界框而非裁剪框。

文档大纲 (书签)

文档大纲是由大纲条目组成的树。这些大纲条目是通过一个大纲字典和许多大纲项目字典定义的。文档目录中的/Outlines指向大纲字典。条目的子条目可以默认展开或收起。大纲字典中的条目如下:

值类型
/Type名称如果存在,必须是/Outlines
/First间接引用字典文档大纲中第一个顶级项的大纲项字典。如果存在任何文档大纲条目,则必需
/Last间接引用字典文档大纲中最后一个顶级项的大纲项字典。如果存在任何文档大纲条目,则必需
/Count整数打开的大纲条目数。如果没有打开的条目,可以省略。

大纲项目字典中的条目如下表所示,*是必选项:

值类型
/Title*文本字串条目文本
/Parent*间接引用字典指向该项目在大纲树中的父节点。可以是另一个大纲项目字典或顶级大纲字典。
/Prev间接引用字典指向同级的前序项目(如果存在的话)
/Next间接引用字典指向同级的下一项目(如果存在的话)
/First间接引用字典指向本条目的第一个子项目(如果存在的话)
/Last间接引用字典指向本条目的最后一个子项目(如果存在的话)
/Count整数该条目下的条目数,如果该条目是展开的则为正值,吧如果是收起的,则为对应的负值。
/Dest名称,字串或数组

一个例子

考虑一个有三页的文件。我们希望构建以下层次结构:

Part 1 (points to page one)
    Part 1A (points to page two)
    Part 1B (points to page three)

相关代码如下例所示。第一,第二和第三页对应的页面对象编号分别是号3,5和7。
对象12是文档目录。对象11是文档大纲字典,对象8,9和10是文档大纲项目字典。

8 0 obj
<< /Parent 10 0 R /Title (Part 1B) /Dest [ 7 0 R /Fit ] /Prev 9 0 R >>
endobj
9 0 obj
<< /Parent 10 0 R /Title (Part 1A) /Dest [ 5 0 R /Fit ] /Next 8 0 R >>
endobj
10 0 obj
<< /Parent 11 0 R /First 9 0 R /Dest [ 3 0 R /Fit ] /Title (Part 1) /Last 8 0 R >>
endobj
11 0 obj
<< /First 10 0 R /Last 10 0 R  >>
endobj
12 0 obj
<< /Outlines 11 0 R /Pages 1 0 R /Type /Catalog >>

Adobe Reader显示文档及其大纲,如下图所示:


译者注:上例中只给出了大纲部分的代码,下面我们给出一个完整的带大纲的PDF代码。

%PDF-1.4
%忏嫌
1 0 obj 
<<
/Outlines 2 0 R
/Pages 3 0 R
/Type /Catalog
>>
endobj 
3 0 obj 
<<
/Kids [4 0 R 5 0 R 6 0 R]
/Count 3
/Type /Pages
>>
endobj 
4 0 obj 
<<
/Parent 3 0 R
/MediaBox [0 0 300 500]
/Resources 7 0 R
/Contents 8 0 R
/Type /Page
>>
endobj 
7 0 obj 
<<
/Font 
<<
/F1 9 0 R
>>
>>
endobj 
9 0 obj 
<<
/BaseFont /Helvetica
/Subtype /Type1
/Type /Font
>>
endobj 
8 0 obj 
<<
/Length 52
>>
stream
BT /F1 20 Tf 20 460 Td (Preface to this book)Tj ET

endstream 
endobj 
5 0 obj 
<<
/Parent 3 0 R
/MediaBox [0 0 300 500]
/Resources 7 0 R
/Contents 10 0 R
/Type /Page
>>
endobj 
10 0 obj 
<<
/Length 49
>>
stream
BT /F1 20 Tf 20 460 Td (this is section 2)Tj ET

endstream 
endobj 
6 0 obj 
<<
/Parent 3 0 R
/MediaBox [0 0 300 500]
/Resources 7 0 R
/Contents 11 0 R
/Type /Page
>>
endobj 
11 0 obj 
<<
/Length 49
>>
stream
BT /F1 20 Tf 20 460 Td (this is section 1)Tj ET

endstream 
endobj 
12 0 obj 
<<
/Title (Section 2)
/Parent 13 0 R
/Dest [5 0 R /Fit]
/Prev 14 0 R
>>
endobj 
14 0 obj 
<<
/Title (Section 1)
/Parent 13 0 R
/Dest [6 0 R /Fit]
/Next 12 0 R
>>
endobj 
13 0 obj 
<<
/Title (Chaper1)
/First 14 0 R
/Parent 2 0 R
/Dest [4 0 R /Fit]
/Count 2
/Last 12 0 R
>>
endobj 
2 0 obj 
<<
/First 13 0 R
/Last 13 0 R
>>
endobj xref
0 15
0000000000 65535 f 
0000000015 00000 n 
0000001192 00000 n 
0000000082 00000 n 
0000000153 00000 n 
0000000482 00000 n 
0000000692 00000 n 
0000000259 00000 n 
0000000377 00000 n 
0000000305 00000 n 
0000000589 00000 n 
0000000799 00000 n 
0000000902 00000 n 
0000001082 00000 n 
0000000992 00000 n 
trailer

<<
/Root 1 0 R
/Size 15
>>
startxref
1241
%%EOF

在Adobe Reader中展现如下:

相应的对象图如下:

XML元数据

从PDF 1.4开始,元数据流可用于将XML元数据附加到整个文档或其中的某个元素上。 文档级元数据流扩展并取代文档信息字典(为了与旧的PDF程序兼容,几乎总是包含该字典)。

元数据以未压缩方式存储,通常不会加密。这样的方式使得外部工具可以很容易地在PDF文件中找到它。

XML使用由可扩展元数据平台(XMP)定义的标记,该标准在Adobe的XMP:可扩展元数据平台, 以及ISO 16684-1中进行了描述。

下面是一个XMP元数据的示例。你可以从文档信息词典中看到一些熟悉的条目。 注意/Type /Metadata /Subtype /XML,该序列将此流标识为XMP元数据。通过使用文档目录中的/Metadata条目将元数据流添加到文档中。

//译者注:原示例的空格和换行有问题,所以换了另外一个真实PDF中的例子
6 0 obj
<</Length 2988/Subtype/XML/Type/Metadata>>stream
<?xpacket begin="锘? id="W5M0MpCehiHzreSzNTczkc9d"?>
<x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 5.4-c006 80.159825, 2016/09/16-03:31:08">
   <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
      <rdf:Description rdf:about=""
            xmlns:xmp="http://ns.adobe.com/xap/1.0/"
            xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/"
            xmlns:dc="http://purl.org/dc/elements/1.1/">
         <xmp:ModifyDate>2021-08-17T15:35:07+08:00</xmp:ModifyDate>
         <xmp:CreateDate>2021-08-17T15:35:07+08:00</xmp:CreateDate>
         <xmp:MetadataDate>2021-08-17T15:35:07+08:00</xmp:MetadataDate>
         <xmpMM:DocumentID>uuid:ca48048c-5b23-4b85-b01b-b6729ddd9a97</xmpMM:DocumentID>
         <xmpMM:InstanceID>uuid:f46a0541-f391-4c44-953d-f1fe33ad8ae4</xmpMM:InstanceID>
         <dc:format>application/pdf</dc:format>
      </rdf:Description>
   </rdf:RDF>
</x:xmpmeta>

注释和超链接

PDF中的注释用于在页面内容本身之外添加注解或交互元素。

在。每个查看器应用(例如Adobe Reader或Mac OS X Preview)都可能以不同的方式显示这些注释, 同一软件的不同版本之间都可能有差异。注释不会影响打印输出。

可以使用页面字典中的条目/Annots下的数组将一个或多个注释与页面相关联。 每个注释都是一个字典。字典中的条目在下表中描述,*为必选项。每种类型的注释都有额外的条目。

值类型
/Type名称如果存在,必须是/Annot
/Subtype*名称该注释的类型
/Rect*矩形注释的位置和大小,默认用户空间单位
/Contents文本字串此注释的文本内容。

我们来看两种注释:文本注释,以及用于在文档中创建超链接的链接注释。 还有许多其他类型的注释,可用于在文档上绘图,高亮文本以及添加打印机标记。 在“文件附件”中,我们使用文件附件注释为单个页面添加附件。

首先来看文本注释。此处/Subtype的值为/Text。我们将额外的注释字典条目/Open设置为true,表明在打开文档时注释将是可见的。使用/C条目将背景颜色设置为白色。具体代码如下。

6 0 obj 
<<
  /Subtype /Text
  /Open true
  /Contents (An example text annotation)
  /Type /Annot
  /Rect [400 100 500 200]
  /C [1 1 1] //RGB (1, 1, 1) i.e., White
>>

/Annots [6 0 R] 
//Extra entry in page dictionary

Adobe Reader中的结果下图所示。注意,Adobe Reader会忽略此处的/Rect条目 - 其他查看者可能会使用它。


现在来看链接注释,我们构建从第一页跳转到到第三页的超链接。 链接注释具有子类型/Link和用于指定目标的/Dest条目构成。/Rect条目定义超链接的区域。

代码如下:

6 0 obj 
<<
  /Subtype /Link
  /Dest [4 0 R /Fit]
  /Type /Annot
  /Rect [45 760 260 800]
>>

/Annots [6 0 R] //Extra entry in page dictionary

Adobe Reader中的结果下图所示。可以使用不同的边框样式,包括使链接矩形不可见的样式。

文件附件

附件是一种在PDF文档中包含一个或多个文件(任何类型)的方法。文件可以附加到整个文档上,也可以附加到单个页面上。通常,PDF查看器将显示附件列表,允许用户打开或保存它们。 例如,可以使用此功能将示例资源与幻灯片演示文稿的PDF捆绑在一起。

嵌入文件本身只包含在流对象中,此时流字典中将会有附加条目/Type /Embedded File。嵌入文件的代码的代码示例如下:

8 0 obj
<< /Type /EmbeddedFile /Length 35 >>
stream
This is a text file attachment...


endstream
endobj

嵌入式文件流有两种完全不同的引用方式:一种用于整个文档的附件,另一种用于特定页面的附件。

要附加到整个文档, 名称字典中需要包含/EmbeddedFiles条目,该条目会被文档目录中的/Names条目引用。代码示例如下:

//文档级附件。嵌入文件为对象8(参看上例)
9 0 obj
<< /Names
     << /EmbeddedFiles
       << /Names
           [ (attachment.txt) << /EF << /F 8 0 R >> /F (attachment.txt) /Type /F >> ] >>
     >>
   /Pages 1 0 R
   /Type /Catalog >>
endobj

要附加到单个页面,需要使用一种特殊类型的注释,通常在页面字典的/Annots字典中列出。代码示例如下:

//特定页面附件。嵌入文件是对象8
9 0 obj
<<
  /Type /Page

  //(Other dictionary entries as usual)

  /Annots
     [ << /FS << /EF << /F 8 0 R >> /F (attachment.txt) /Type /F >>
          /Subtype /FileAttachment
          /Contents (attachment.txt)
          /Rect [ 18 796.88976378 45 823.88976378 ]
     >> ]
>>
endobj

Adobe Reader在侧栏中显示附件如下图所示。

以上是关于文档元数据和导航的主要内容,如果未能解决你的问题,请参考以下文章

文档元数据和导航

PDF Explained(翻译)第七章 文档元数据和导航

facebook开源库-Bolts中文文档

Component.js 中的元数据是啥?

OData 带更新的实例,并能取得元数据格式类型

Vue的路由Router之导航钩子和元数据及匹配