Technical Article

PDF-bestandsstructuur begrijpen: een technisch overzicht

· PDF-structuur

Technisch overzicht van de bestandsstructuur van PDF en de onderdelen die een PDF-document leesbaar maken.

Dit artikel is bedoeld voor ontwikkelaars die met pdf-structuur werken. Productnamen, API-namen, bestandsnamen en codefragmenten zijn bewust ongewijzigd gehouden, zodat de voorbeelden direct met de oorspronkelijke documentatie en broncode te vergelijken zijn.

Overzicht

De pagina beschrijft het probleemgebied, de relevante implementatiekeuzes en de controles die belangrijk zijn voordat de oplossing in een echte toepassing wordt gebruikt.

Codevoorbeeld

Het onderstaande codefragment is ongewijzigd uit de Engelse bron overgenomen om identifiers, API-aanroepen en syntaxis exact te behouden.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
%PDF-1.0                          % Header starts here
%âãÏÓ
 
1 0 obj                           % Body starts here
<<
/Kids [2 0 R]
/Count 1
/Type /Pages
>>
endobj
 
2 0 obj
<<
/Rotate 0
/Parent 1 0 R
/Resources 3 0 R
/MediaBox [0 0 612 792]
/Contents [4 0 R]
/Type /Page
>>
endobj
 
3 0 obj
<<
/Font
<<
/F0
<<
/BaseFont /Times-Italic
/Subtype /Type1
/Type /Font
>>
>>
>>
endobj
 
4 0 obj
<<
/Length 65
>>
stream
1. 0. 0. 1. 50. 700. cm BT
  /F0 36. Tf
  (Hello, World!) Tj
ET
endstream
endobj
 
5 0 obj
<<
/Pages 1 0 R
/Type /Catalog
>>
endobj
 
xref                              % Cross-reference table starts here
0 6
0000000000 65535 f
0000000015 00000 n
0000000074 00000 n
0000000192 00000 n
0000000291 00000 n
0000000409 00000 n
 
trailer                           % Trailer starts here
<<
/Root 5 0 R
/Size 6
>>
startxref
459
%%EOF
1
2
%PDF-1.0
%âãÏÓ
1
2
3
[object_number] [generation_number] obj
[object_content]
endobj
1
2
3
4
5
6
7
1 0 obj
<<
/Kids [2 0 R]
/Count 1
/Type /Pages
>>
endobj
1
2
3
4
5
6
7
8
xref
0 6                              % Six entries starting at object 0
0000000000 65535 f               % Special entry for free objects
0000000015 00000 n               % Object 1 at byte offset 15
0000000074 00000 n               % Object 2 at byte offset 74
0000000192 00000 n               % Object 3 at byte offset 192
0000000291 00000 n               % Object 4 at byte offset 291
0000000409 00000 n               % Object 5 at byte offset 409
1
2
3
4
5
6
7
8
trailer
<<
/Root 5 0 R                      % Document catalog reference
/Size 6                          % Number of xref entries
>>
startxref
459                              % Byte offset of xref table
%%EOF                            % End-of-file marker
1
2
3
4
5
% Integer examples
0 +1 -1 63
 
% Real number examples  
0.0 0. .0 -0.004 65.4
1
2
3
4
5
6
7
8
% Simple string
(Hello, World!)
 
% String with escaped characters
(Some \\ escaped \(characters\))
 
% String with balanced parentheses (no escaping needed)
(Red (Rouge))
1
2
<4F6Eff00>                       % Bytes 0x4F, 0x6E, 0xFF, 0x00
<48656C6C6F>                     % "Hello" in ASCII hex
1
2
3
4
/French                         % Simple name
/                               % Valid name (just the slash)
/Websafe#20Dark#20Green         % Name with encoded spaces (#20 = space)
/A#42                           % Name with encoded character (#42 = 'B')
1
2
3
true                             % Boolean true
false                            % Boolean false
null                             % Null object
1
2
3
[0 0 400 500]                   % Four integers (typical rectangle)
[/Green /Blue [/Red /Yellow]]   % Mixed types with nested array
[1 0 R 2 0 R 3 0 R]             % Array of indirect references
1
2
3
4
5
6
7
8
<</One 1 /Two 2 /Three 3>>      % Simple mappings
<<                               % Multi-line dictionary
  /Type /Page
  /Parent 1 0 R
  /Resources 3 0 R
  /MediaBox [0 0 612 792]
  /Contents [4 0 R]
>>
1
2
3
4
5
6
7
8
9
10
11
12
4 0 obj
<<
/Length 65                       % Stream length in bytes
/Filter /FlateDecode            % Optional compression filter
>>
stream
1. 0. 0. 1. 50. 700. cm BT      % Binary or text data
  /F0 36. Tf
  (Hello, World!) Tj
ET
endstream
endobj
1
2
6 0 R                            % Reference to object 6, generation 0
<</Resources 10 0 R /Contents [4 0 R]>>  % Dictionary using references
1
2
/Filter [/ASCII85Decode /DCTDecode]    % JPEG data then ASCII85 encoded
/Filter [/ASCIIHexDecode /FlateDecode] % Deflate compression then hex encoding
1
2
3
4
5
6
7
8
9
10
11
12
%PDF-1.4
%âãÏÓ
4 0 obj                          % Linearization dictionary
<< /E 200967                     % End of first page
   /H [ 667 140 ]               % Hint stream location and length
   /L 201431                    % File length
   /Linearized 1                % Linearization flag
   /N 1                         % Number of pages
   /O 7                         % First page object number
   /T 201230                    % Traditional xref table offset
>>
endobj
1
2
3
4
5
6
7
8
9
10
pdfobject ::= Null
            | Boolean of bool
            | Integer of int  
            | Real of real
            | String of string
            | Name of string
            | Array of pdfobject array
            | Dictionary of (string, pdfobject) array
            | Stream of (pdfobject, bytes)
            | Indirect of int
1
2
3
4
5
Dictionary [
  ("Kids", Array [Indirect 2]);
  ("Count", Integer 1);
  ("Type", Name "Pages")
]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
% Linearize PDF for web optimization
pdfopt input.pdf output.pdf
 
% Decompress streams for manual inspection  
pdftk input.pdf output decompressed.pdf uncompress
 
% Extract and analyze PDF structure
pdf-parser --stats document.pdf
 
% Repair corrupted PDF files
pdftk broken.pdf output repaired.pdf
 
% Extract specific pages
pdftk document.pdf cat 1-3 output pages1-3.pdf
 
% Get comprehensive PDF information
pdfinfo -meta -struct document.pdf
 
% Convert PDF to PostScript for analysis
pdftops document.pdf document.ps

Praktische aandachtspunten

  • Controleer invoerbestanden en foutpaden expliciet voordat u de routine in productie gebruikt.
  • Houd paginalay-out, lettertypen en coördinaten reproduceerbaar, vooral bij server-side verwerking.
  • Test het resultaat in meer dan één PDF-viewer wanneer rendering, annotaties of interactieve elementen belangrijk zijn.
  • Laat componentlevensduur en bestandshandles altijd via try/finally-achtige patronen opruimen.