当前位置: 首页 > news >正文

PDF标准详解(二)——PDF 对象

上一篇文章我们介绍了一个PDF文档应该包含的最基本的结构,并且手写了一个最简单的 “Hello World” 的PDF文档。后面我们介绍新的PDF标准给出示例时将以这个文档为基础,而不再给出完整的文档示例,小伙伴想自己测试可以根据上一节的文档来进行配置。

对象

上一节我们看到一个个奇奇怪怪的元素,可能也好奇它们的写法,现在我们来正式介绍它们的相关内容,它们就是PDF文档中一个个的对象。

PDF 支持5种基本对象:

  1. 整数和实数:例如43和12.2 这种数字
  2. 字符串,PDF种字符串被包裹在小括号中,例如上一节中的 (hello world), 我们也可以给字符串制定编码,这个在后面介绍
  3. 名称:一般用于字典中的键,以/ 开头,例如上一节中的 /Page 就是一个名称的对象
  4. 布尔值: 由关键字 true 和 false表示
  5. null 对象,由关键字 null 表示

PDF支持3种复合对象

  1. 数组: 包含其他对象的有序集合,数组中的元素可以是其他任何类型的对象,例如可以像 [0 0 0 0 1] 这样只包含数字,也可以像上一节中的 [2 0 R] 包含其他对象的一个引用
  2. 字典: 字典是由无序对的集合组成,将名称映射到对象。字典中的映射被包含在 <<>> 对中,例如 <</Kids [2 0 R]>> 就是一个字典,它将Kids这个名称映射到 [2 0 R] 这个间接引用的对象上
  3. 流:流中一般包含二进制的数据流以及描述属性的字典,一般page中的content都是一个个的流对象。

间接引用

间接引用形成从一个对象到另一个对象的链接,为了将PDF拆分成一个个单独的对象,我们通过间接引用将它们链接在一起,例如上一篇文章中提到的

1 0 obj 
<<
/Kids [2 0 R]
/Count 1
/Type /Pages
>>

对象中就包含间接引用,PDF解析器,知道这个对象是一个Pages对象之后,可以通过Kids 对象指定的间接引用对象知道,当前PDF文档只有一页,这个页面对象就是2 0 这个对象。 这里的R 代表 reference 也就是引用,它是一个关键字,前面的 2 0 代表的是对象编号是2,世代号是0(这里我们不考虑世代号,默认的世代号都是0)

流和过滤器

流用于存储二进制数据,它们由字典和一大块二进制数据组成,字典根据流所放置的特定用途,列出数据的长度,以及可选的其他参数。

从语法上将,流由字典组成,后跟 stream 关键字,换行符,0个或者多个字节的数据,另一个换行符,最后是一个endstream 关键字。根据上一篇文章中给出的页面流对象的定义来看

4 0 obj 
<<
/Length 202 % 流的长度
>>
stream %关键字
1. 0. 0. 1. 50. 700. cm % 202 字节的数据,这里是图形流,下面是图形流的数据
BT/F0 36. Tf(Hello, World!) Tj
ET
endstream % 流对象结束的关键字 
endobj

相关文章:

  • 2024.3.2 训练记录(6)
  • 排序刷题12 -双向排序
  • Redis之一: 简介及环境安装搭建
  • CNN-LSTM-Attention混合神经网络归时序预测的MATLAB实现(源代码)
  • ESP-VO 论文阅读
  • Fastjson2 <== 2.0.26反序列漏洞
  • redis 为什么会阻塞
  • 二刷代码随想录算法训练营第七天 |454.四数相加II 383. 赎金信 15. 三数之和 18. 四数之和
  • Python 编辑工具 Jupyter notebook
  • PTA天梯 L1-087 机工士姆斯塔迪奥
  • SQL中把datetime 转为字符串
  • 多模态论文阅读--V*指导视觉搜索成为多模态大语言模型的核心机制
  • Java 石头剪刀布小游戏
  • 【MySQL】查询语句:条件、排序和分页
  • Thinkphp框架漏洞--->5.0.23 RCE
  • ES6指北【2】—— 箭头函数
  • axios请求、和返回数据拦截,统一请求报错提示_012
  • Git学习与使用心得(1)—— 初始化
  • iOS编译提示和导航提示
  • Java 9 被无情抛弃,Java 8 直接升级到 Java 10!!
  • JS数组方法汇总
  • nodejs:开发并发布一个nodejs包
  • PHP CLI应用的调试原理
  • REST架构的思考
  • Sublime text 3 3103 注册码
  • Vue源码解析(二)Vue的双向绑定讲解及实现
  • 程序员最讨厌的9句话,你可有补充?
  • 基于Dubbo+ZooKeeper的分布式服务的实现
  • 理解在java “”i=i++;”所发生的事情
  • 世界编程语言排行榜2008年06月(ActionScript 挺进20强)
  • 我的面试准备过程--容器(更新中)
  • 译有关态射的一切
  • 深度学习之轻量级神经网络在TWS蓝牙音频处理器上的部署
  • 【运维趟坑回忆录 开篇】初入初创, 一脸懵
  • postgresql行列转换函数
  • 正则表达式-基础知识Review
  • ​secrets --- 生成管理密码的安全随机数​
  • # Pytorch 中可以直接调用的Loss Functions总结:
  • #1015 : KMP算法
  • #Linux(权限管理)
  • #控制台大学课堂点名问题_课堂随机点名
  • (01)ORB-SLAM2源码无死角解析-(56) 闭环线程→计算Sim3:理论推导(1)求解s,t
  • (1)Android开发优化---------UI优化
  • (libusb) usb口自动刷新
  • (独孤九剑)--文件系统
  • (附源码)springboot学生选课系统 毕业设计 612555
  • (附源码)基于SpringBoot和Vue的厨到家服务平台的设计与实现 毕业设计 063133
  • (十五)devops持续集成开发——jenkins流水线构建策略配置及触发器的使用
  • (转)http协议
  • .NET 2.0中新增的一些TryGet,TryParse等方法
  • .NET Micro Framework初体验
  • .NET MVC之AOP
  • .net6使用Sejil可视化日志
  • .Net下的签名与混淆
  • @DataRedisTest测试redis从未如此丝滑