【问题标题】:What is the smallest possible valid PDF?什么是最小的有效 PDF?
【发布时间】:2013-06-21 05:02:19
【问题描述】:

出于好奇,看过the smallest GIF,最小的有效PDF文件是什么?

【问题讨论】:

  • 取决于您如何创建它。您可能自己(在编辑器中)编写一个比应用程序生成的更小的。
  • 尝试将“showpage”(不带引号)输入到 ghostscript 或 ps2pdf。

标签: pdf optimization pdf-generation


【解决方案1】:

我将举一个我认为是最小有效“通用”PDF 的示例。直到我注意到使用 PDF 的整个精神是确保它在所有设备及其 PDF 阅读器上呈现完全相同。然而,在交叉检查我的“完美小型格式良好的 PDF”时,我发现了这一点。

所以基本规则是“最小可能的有效 PDF”,但我认为这种短缺应该算作无效 PDF,因为它不符合“适合用途”的概念,因此最小 PDF本身必须至少包含至少一种固定工作字体的方法。

为了解释我提出的解决方案以及为什么它在这里不够完美,由于剪切和粘贴,它处于粗略形式。

%PDF-1.0
%µ¶

1 0 obj
<</Type/Catalog/Pages 2 0 R>>
endobj

2 0 obj
<</Kids[3 0 R]/Count 1/Type/Pages/MediaBox[0 0 595 792]>>
endobj

3 0 obj
<</Type/Page/Parent 2 0 R/Contents 4 0 R/Resources<<>>>>
endobj

4 0 obj
<</Length 58>>
stream
q
BT
/ 96 Tf
1 0 0 1 36 684 Tm
(Hello World!) Tj
ET
Q

endstream
endobj

xref
0 5
0000000000 65536 f 
0000000016 00000 n 
0000000062 00000 n 
0000000136 00000 n 
0000000209 00000 n 

trailer
<</Size 5/Root 1 0 R>>
startxref
316
%%EOF

虽然问题的规则没有定义,但我已经包含了一些过去的用户问题经验。

您可能注意到的第一个区别是第二个 obj 中的媒体框是一个混合 MediaBox[0 0 595 792],它是最小 A4 宽度和最小最大 US Letter 高度,因为否则大多数国家的“通用页面”会强制使用第二张纸 @ 100对于语言环境默认设置的页面定义太宽或太高,百分比打印。

当前的问题在 3rd obj 中得到证明,因为没有为资源设置字体,因此以 minimal 为目标,我在没有定义字体的情况下竞赛的 PDF 将是无效的。

因此,到目前为止,包括我自己在内的所有答案似乎都不会生成一个 PDF,它将 "WORK" 作为“有效”意味着生成相同的打印输出,无论平台或查看器如何。

@mkl 你准备好拍出最好的照片了吗?

【讨论】:

    【解决方案2】:

    我需要一个可被 PDF 转换器使用的 PDF 版本(A4 格式问题.. 以上所有结构都适用于 Adob​​e Reader 和 Chrome,但不适用于需要 DIN A4 的 PDF 转换器)。 我找到了这个网站,并且这个 PDF 与我正在使用的 PDF 转换器工作得很好:https://help.callassoftware.com/m/73261/l/798383-how-to-create-a-simple-pdf-file

    【讨论】:

      【解决方案3】:

      根据这里的所有答案,这是最小的带文本的 PDF:

      SMALL_PDF = (
          b"%PDF-1.2 \n"
          b"9 0 obj\n<<\n>>\nstream\nBT/ 32 Tf(  YOUR TEXT HERE   )' ET\nendstream\nendobj\n"
          b"4 0 obj\n<<\n/Type /Page\n/Parent 5 0 R\n/Contents 9 0 R\n>>\nendobj\n"
          b"5 0 obj\n<<\n/Kids [4 0 R ]\n/Count 1\n/Type /Pages\n/MediaBox [ 0 0 250 50 ]\n>>\nendobj\n"
          b"3 0 obj\n<<\n/Pages 5 0 R\n/Type /Catalog\n>>\nendobj\n"
          b"trailer\n<<\n/Root 3 0 R\n>>\n"
          b"%%EOF"
      )
      

      作为base64。复制它并在 Chrome 中测试:

      数据:应用/ PDF; BASE64,JVBERi0xLjIgCjkgMCBvYmoKPDwKPj4Kc3RyZWFtCkJULyAzMiBUZiggIFlPVVIgVEVYVCBIRVJFICAgKScgRVQKZW5kc3RyZWFtCmVuZG9iago0IDAgb2JqCjw8Ci9UeXBlIC9QYWdlCi9QYXJlbnQgNSAwIFIKL0NvbnRlbnRzIDkgMCBSCj4 + CmVuZG9iago1IDAgb2JqCjw8Ci9LaWRzIFs0IDAgUiBdCi9Db3VudCAxCi9UeXBlIC9QYWdlcwovTWVkaWFCb3ggWyAwIDAgMjUwIDUwIF0KPj4KZW5kb2JqCjMgMCBvYmoKPDwKL1BhZ2VzIDUgMCBSCi9UeXBlIC9DYXRhbG9nCj4 + CmVuZG9iagp0cmFpbGVyCjw8Ci9Sb290IDMgMCBSCj4 + CiUlRU9G P>

      要使页面更大,请调整 MediaBox 尺寸:)

      /媒体框[0 0 250 50]

      【讨论】:

        【解决方案4】:

        根据这个Ange Albertini lecture,最小的有效PDF是36字节:

        %PDF-(NULL)预告片>>>>>

        其中 (NULL) 是不可打印的 ASCII 0 字符。

        然而,正如 Ange 所指出的,虽然此 PDF 在技术上是有效的,但大多数 PDF 阅读器应用程序会仅根据大小将其视为无效,从而无法打开它。

        【讨论】:

        • 它不是技术上有效的,根据规范(这比讲座更重要)有多个问题,缺少交叉引用,直接对象需要间接引用, ...
        【解决方案5】:

        在 Java 中,使用这个:

         private static String samplepdf = "255044462D312E0D747261696C65723C3C2F526F6F743C3C2F50616765733C3C2F4B6964735B3C3C2F4D65646961426F785B302030203320335D3E3E5D3E3E3E3E3E3E";
        

        然后

        byte[] bytes = hexStringToByteArray(samplepdf);
        

        ...

        public byte[] hexStringToByteArray(String s) {
            int len = s.length();
            byte[] data = new byte[len / 2];
            for (int i = 0; i < len; i += 2) {
                data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
                        + Character.digit(s.charAt(i + 1), 16));
            }
            return data;
        }
        

        【讨论】:

        • OP 要求尽可能小的有效 PDF 文件;根据规范,您的无效。
        【解决方案6】:

        我无法打开 hello world 示例。

        对于带有文本内容的小文件:

        %PDF-1.2 
        9 0 obj
        <<
        >>
        stream
        BT/ 9 Tf(Test)' ET
        endstream
        endobj
        4 0 obj
        <<
        /Type /Page
        /Parent 5 0 R
        /Contents 9 0 R
        >>
        endobj
        5 0 obj
        <<
        /Kids [4 0 R ]
        /Count 1
        /Type /Pages
        /MediaBox [ 0 0 99 9 ]
        >>
        endobj
        3 0 obj
        <<
        /Pages 5 0 R
        /Type /Catalog
        >>
        endobj
        trailer
        <<
        /Root 3 0 R
        >>
        %%EOF
        

        【讨论】:

        • 这不行,你需要定义一个字体资源并在页面内容中选择它才能显示文本。
        • 此文件实际上在 Mac OS X El Capitan 下打开,而使用 PDF1.0 评分最高的答案却没有。
        • 下铬也打开,数据:应用/ PDF; BASE64,JVBERi0xLjIgCjkgMCBvYmoKPDwKPj4Kc3RyZWFtCkJULyA5IFRmKFRlc3QpJyBFVAplbmRzdHJlYW0KZW5kb2JqCjQgMCBvYmoKPDwKL1R5cGUgL1BhZ2UKL1BhcmVudCA1IDAgUgovQ29udGVudHMgOSAwIFIKPj4KZW5kb2JqCjUgMCBvYmoKPDwKL0tpZHMgWzQgMCBSIF0KL0NvdW50IDEKL1R5cGUgL1BhZ2VzCi9NZWRpYUJveCBbIDAgMCA5OSA5IF0KPj4KZW5kb2JqCjMgMCBvYmoKPDwKL1BhZ2VzIDUgMCBSCi9UeXBlIC9DYXRhbG9nCj4 + CmVuZG9iagp0cmFpbGVyCjw8Ci9Sb290IDMgMCBSCj4 + CiUlRU9G 跨度>
        • @yms 你有什么例子吗?
        【解决方案7】:

        我想我会制作一个显示“Hello World”的最小 pdf。文字在左下角。对不起 9 点字体,任何更大的都会花费额外的字节:)

        Adobe Reader X 为 172 字节(如果保存时仅包含换行符且没有尾随换行符或空字节):

        %PDF-1.
        1 0 obj<</Kids[<</Parent 1 0 R/Resources<<>>/Contents 2 0 R>>]>>endobj 2 0 obj<<>>stream
        BT/ 9 Tf(Hello World)' ET
        endstream
        endobj trailer<</Root<</Pages 1 0 R>>>>
        

        Chrome 的内置 PDF 查看器为 120 字节:

        %PDF 1 0 obj<</Pages<</Kids[<</Contents<<>>stream
        BT 9 Tf(Hello World)' ET endstream>>]>>>>endobj trailer<</Root 1 0 R>>
        

        要在 Chrome 中轻松查看此内容,请将此 URI 粘贴到地址栏中(所以我不会链接到它,并且在其他浏览器中根本无法使用):

        data:application/pdf,%25PDF%201%200%20obj%3C%3C%2FPages%3C%3C%2FKids%5B%3C%3C%2FContents%3C%3C%3E%3Estream%0ABT%209%20Tf(Hello%20World)'%20ET%20endstream%3E%3E%5D%3E%3E%3E%3Eendobj%20trailer%3C%3C%2FRoot%201%200%20R%3E%3E
        

        【讨论】:

        • 相当小。 ;) 但是,根据规范,无效。
        • 不会在 Chrome 中为我打开。
        【解决方案8】:

        这是一个有趣的问题。看书,你可以从这个开始:

        %PDF-1.0
        1 0 obj<</Type/Catalog/Pages 2 0 R>>endobj 2 0 obj<</Type/Pages/Kids[3 0 R]/Count 1>>endobj 3 0 obj<</Type/Page/MediaBox[0 0 3 3]>>endobj
        xref
        0 4
        0000000000 65535 f
        0000000010 00000 n
        0000000053 00000 n
        0000000102 00000 n
        trailer<</Size 4/Root 1 0 R>>
        startxref
        149
        %EOF
        

        这是 291 字节的 PDF 欢乐。 Acrobat 打开它,但它有些抱怨。里面有一页,是 3/72" 正方形,是规范允许的最小值。

        但是,Acrobat X 甚至不再需要交叉引用表了,所以我们可以把它去掉:

        %PDF-1.0
        1 0 obj<</Type/Catalog/Pages 2 0 R>>endobj 2 0 obj<</Type/Pages/Kids[3 0 R]/Count 1>>endobj 3 0 obj<</Type/Page/MediaBox[0 0 3 3]>>endobj
        trailer<</Size 4/Root 1 0 R>>
        

        Acrobat 抱怨,但打开它。现在我们有 178 个字节。 事实证明,您不需要预告片中的 /Size 。现在我们在 172:

        %PDF-1.0
        1 0 obj<</Type/Catalog/Pages 2 0 R>>endobj 2 0 obj<</Type/Pages/Kids[3 0 R]/Count 1>>endobj 3 0 obj<</Type/Page/MediaBox[0 0 3 3]>>endobj
        trailer<</Root 1 0 R>>
        

        事实证明,您的字典中不需要所有那些讨厌的 /Type 元素:

        %PDF-1.0
        1 0 obj<</Pages 2 0 R>>endobj 2 0 obj<</Kids[3 0 R]/Count 1>>endobj 3 0 obj<</MediaBox[0 0 3 3]>>endobj
        trailer<</Root 1 0 R>>
        

        现在我们是 138 字节。

        事实证明,当规范说“应该是间接引用”并且需要 /Count 并且标题“必须”是 %PDF-1.0 时,他们提出了松散的建议。这是我能做的最小的并且可以在 Acrobat X 中打开:

        %PDF-1.
        trailer<</Root<</Pages<</Kids[<</MediaBox[0 0 3 3]>>]>>>>>>
        

        70 字节。

        现在,我的编辑器使用 Windows 换行规则,但 Acrobat 接受 Windows、Mac 或 Unix 约定,因此通过使用十六进制编辑器,我将 \r\n 替换为 \r 并完全删除了最后一个换行符,这让我67字节

        25 50 44 46 2D 31 2E 0D 74 72 61 69 6C 65 72 3C 
        3C 2F 52 6F 6F 74 3C 3C 2F 50 61 67 65 73 3C 3C 
        2F 4B 69 64 73 5B 3C 3C 2F 4D 65 64 69 61 42 6F 
        78 5B 30 20 30 20 33 20 33 5D 3E 3E 5D 3E 3E 3E 
        3E 3E 3E 
        

        我尝试删除最后一个结束字典 (>>),但 Acrobat 不会这样做。 Google Chrome (FoxIt) 内置的 PDF 阅读无法打开。

        作为 PostScript(哈!看看我在那里做了什么?),如果您同意 Acrobat “修复”文件,它会增加 3550 字节,其中大部分是可选的元数据,但它留下了一些明确的规范违规。

        【讨论】:

        • 事实证明,当规范说“应该是间接引用”并且需要 /Count 并且标题“必须”是 %PDF-1.0 时,它们变得松散了建议。 不,这些不是松散的建议,这些是有效性要求。即使某些 PDF 查看器不强制执行它们,不遵循它们也意味着无效,并且 OP 要求提供有效的 PDF。
        • 已接受,因为答案以 minimum allowed by the spec 开头,然后超出范围。很好的答案,谢谢! :)
        • 这就是规范。 PDF中的对象图有循环。
        • 我需要一个 PDF 的 base64 表示。所以,如果有人感兴趣,这里是 138 字节版本的 base64 字符串:JVBERi0xLjAKMSAwIG9iajw8L1BhZ2VzIDIgMCBSPj5lbmRvYmogMiAwIG9iajw8L0tpZHNbMyAw\nIFJdL0NvdW50IDE+PmVuZG9iaiAzIDAgb2JqPDwvTWVkaWFCb3hbMCAwIDMgM10+PmVuZG9iagp0\ncmFpbGVyPDwvUm9vdCAxIDAgUj4+Cg==
        • ...这是 67 字节版本的 base64 字符串版本:JVBERi0xLg10cmFpbGVyPDwvUm9vdDw8L1BhZ2VzPDwvS2lkc1s8PC9NZWRpYUJveFswIDAgMyAzXT4+XT4+Pj4+Pg==
        猜你喜欢
        • 1970-01-01
        • 2012-01-10
        • 2011-02-19
        • 1970-01-01
        • 2020-07-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多