一、PDF 里的"图像"和"外部对象"是什么?
简单来说,PDF 页面就像一张大画布 ,而 外部对象(XObject) 就是预先准备好、可以随时贴上去的小画布。
每张图片、每个可复用图形,都是一个 XObject。
举个例子:
假设你在 WPS 里插入了一张公司 Logo,PDF 导出后不会把这张图直接画进页面文字流里,而是:
- 把这张图单独存成一个对象(小画布);
- 在页面内容里,只写一句话告诉 PDF 阅读器去把那张图画上去。
二、Image XObject对象
当你在WPS中插入一张图片时,会在pdf底层生成一个 Image XObject对象, 它是 XObject 的一种类型,专门用于存放位图数据,比如 PNG、JPEG 等。
它的定义看起来像这样:
css
10 0 obj
<< /Type /XObject
/Subtype /Image
/Width 600
/Height 400
/ColorSpace /DeviceRGB
/BitsPerComponent 8
/Filter /DCTDecode
>>
stream
... JPEG 图片二进制数据 ...
endstream
endobj
上面这个对象(编号 10)保存了整张图片的数据。
三、Do 操作符
PDF 页面并不会直接存图片,而是通过 /名字 Do
的方式引用。
例如:
vbnet
/KSPX1 Do
这就相当于说:"把名字叫 KSPX1 的图像贴到这里"。
名字 /KSPX1
并不是固定的,它来自于页面的资源字典(Resources)。
在你的 PDF 里看到 /KSPX1 Do
,说明资源里定义了一个 /KSPX1
的图片对象。
四、WPS图片对象的完整结构
假设你在 WPS 中插入了一张图片(比如一张 PNG),
WPS 导出 PDF 后大致结构如下:
1️⃣ 页面资源定义
javascript
<<
/Type /Page
/Resources <<
/XObject << /KSPX1 10 0 R >> % 图片注册在资源字典中
/ProcSet [/PDF /ImageC]
>>
/Contents 20 0 R
>>
2️⃣ 图片对象(Image XObject)
css
10 0 obj
<< /Type /XObject
/Subtype /Image
/Width 1200
/Height 800
/ColorSpace /DeviceRGB
/BitsPerComponent 8
/Filter /DCTDecode
/Length 123456
>>
stream
... 图片数据(压缩后的二进制) ...
endstream
endobj
3️⃣ 页面内容流(Contents)
erlang
20 0 obj
<< /Length 44 >>
stream
q
1 0 0 1 100 200 cm % 移动到页面坐标(100, 200)
100 0 0 100 0 0 cm % 缩放或旋转(视情况)
/KSPX1 Do % 绘制图片(资源名 KSPX1)
Q
endstream
endobj
在这里:
/KSPX1
是资源名称;10 0 R
是图片对象的引用;/KSPX1 Do
就是告诉 PDF 阅读器:"把第10号图片对象画在当前坐标处"。
这就是你在 WPS 里插入图片后,PDF 实际干的事情。
五、其他图片形式
1️⃣ 内联图像(Inline Image)
有时候图片很小,比如一个小图标。
为了方便,不用单独定义成对象,可以直接写进内容流里:
python
BI
/W 32 /H 32 /CS /RGB /BPC 8
ID
... 图片数据 ...
EI
这是内联图像,不需要 /Do
引用。
2️⃣ 外部图像(External Image)
PDF 里也可以引用外部文件的图片,比如网络图片:
javascript
/F << /FS /URL /F (http://example.com/logo.jpg) >>
PDF 阅读器会在需要时加载。
六、总结
总的来说,在pdf中图片的渲染流程为:
页面内容告诉 PDF:用
/KSPX1 Do
贴一张图;
/KSPX1
在资源里指向图片对象(10 0 obj);图片对象里存着真实的图像数据。
图片对象类型对比:
类型 | 说明 | 是否可复用 | 数据位置 |
---|---|---|---|
Image XObject | 普通图片 | ✅ 是 | 独立对象 |
Form XObject | 一组图形或文字 | ✅ 是 | 独立对象 |
Inline Image | 小图标 | ❌ 否 | 内容流中 |
External Image | 外部引用 | ✅ 是 | 文件外部 |
PDF 里的图片不是直接画上去的,而是通过 XObject 引用。
/KSPX1 Do
就像调用函数一样,把图片从资源库"贴"到页面上。所以无论是
/Im1
还是/KSPX1
,它们的本质都一样------
一个资源名 + 一个图片对象。