代码之家  ›  专栏  ›  技术社区  ›  Marcos Silva

不使用X-Object压缩PDF

  •  -1
  • Marcos Silva  · 技术社区  · 6 年前

    我有几种方法来处理PDF文件,例如将它们转换为。对jpg图像进行压缩。现在,我有一个没有X-Object的pdf文件,也就是说,我无法将其转换为jpg来压缩它们。然后我决定抓取整个pdf文件并尝试某种压缩方法,我尝试使用iText Stamper和pdfBox。addCompression(已弃用),但到目前为止还没有一个有效。以下内容:

        public static byte[] compressPdf(final byte[] imageBytes) {
        try (ByteArrayOutputStream out = new ByteArrayOutputStream()){
    
            final PdfReader reader = new PdfReader(imageBytes);
            final PdfStamper stamper = new PdfStamper(reader, out, PdfWriter.VERSION_1_7);
    
            stamper.getWriter().setFullCompression();
            stamper.getWriter().setCompressionLevel(9);
    
            int total = reader.getNumberOfPages() + 1;
            for (int i = 1; i < total; i++) {
                reader.setPageContent(i, reader.getPageContent(i));
            }
    
            stamper.close();
            reader.close();
    
            return out.toByteArray();
        } catch (Exception e) {
            e.printStackTrace();
        }
    
        return null;
    }
    

    请注意压模。全压缩或压模。setcompressionlevel不工作。

    1 回复  |  直到 6 年前
        1
  •  1
  •   Joris Schellekens    6 年前

    您正在显示的PDF文档只是图像的包装。

    请允许我详细说明。

    通常,PDF由查看器的说明组成。 类似于:

    • 转到坐标50,50
    • 将字体设置为Helvetica,大小为12
    • 绘制字符“H”的图示符

    这些指令被收集到对象中。同样,它们使用的资源(如图像、字体等)也被分组到对象中。

    每个对象都会被分配一个数字。这些是外部参照中的数字。

    当iText尝试应用压缩时,它将查找对象流(指令流和字体流等),并尝试压缩这些流。

    您的PDF仅包含1幅图像。

    iText不会压缩图像(因为这可能会导致图像质量下降)。

    您可以做什么:

    • 请勿使用扫描文档,请使用“真实”PDF文档(您的最终用户将不胜感激)
    • 从PDF中提取图像(使用iText),压缩图像(使用图像处理库),然后将图像重新插入到资源中。