前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >PDF Explained(翻译)第七章 文档元数据和导航

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

作者头像
跑马溜溜的球
发布2021-08-20 16:15:52
1.1K0
发布2021-08-20 16:15:52
举报
文章被收录于专栏:日积月累1024

本文是对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

名称,字串或数组

一个例子

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

代码语言:javascript
复制
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是文档大纲项目字典。

代码语言:javascript
复制
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代码。

代码语言:javascript
复制
%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条目将元数据流添加到文档中。

代码语言:javascript
复制
//译者注:原示例的空格和换行有问题,所以换了另外一个真实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条目将背景颜色设置为白色。具体代码如下。

代码语言:javascript
复制
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条目定义超链接的区域。

代码如下:

代码语言:javascript
复制
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。嵌入文件的代码的代码示例如下:

代码语言:javascript
复制
8 0 obj
<< /Type /EmbeddedFile /Length 35 >>
stream
This is a text file attachment...


endstream
endobj

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

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

代码语言:javascript
复制
//文档级附件。嵌入文件为对象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字典中列出。代码示例如下:

代码语言:javascript
复制
//特定页面附件。嵌入文件是对象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在侧栏中显示附件如下图所示。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021/08/17 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 书签与定位(Destinations)
    • 定位(Destinations)
      • 文档大纲 (书签)
        • 一个例子
    • XML元数据
    • 注释和超链接
    • 文件附件
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档