PDF有损压缩

5
我正在寻找一个库或命令行程序,可以压缩 PDF 文件。
压缩速度和文件大小非常重要。
PDF 文件中充满了非常大的印刷质量图像。
Adobe Acrobat 可以进行高质量、快速的压缩,但不允许通过编程接口保存“减小文件大小的 PDF” 。
Ghostscript 可以进行高质量压缩,但耗时太长(需要数分钟)。

2
这是我目前找到的最佳解决方案:gswin64c.exe -dQUIET -dBATCH -dNOPAUSE -dNOGC -dPDFSETTINGS=/screen -sDEVICE=pdfwrite -sOutputFile=compressed.pdf input.pdf。它只需要大约20秒就可以将一个126 MB的文件压缩至3.2 MB。 - user1359680
感谢user1359680。这很简单而且很棒,只是在我的情况下,gswin32c.exe已经存在于我的系统中。我将把它包装成一个.cmd一行脚本,并将其放入我的SendTo文件夹中,以便轻松右键应用。 - Marcos
更新:我选择了Neevia CompressPDF,价格为99美元。它不会压缩字体或干扰文本。Ghostscript有时会从可搜索文本层中删除字母。另一个解决方案是使用IDR Solutions的jpdf2html.jar将PDF转换为HTML5,但需要购买许可证(2500美元)。 - user1359680
2个回答

1

如果商业库是一个选项,您可以尝试使用Amyuni PDF Creator。它有 .net 版本(C#/VB.Net 等)和 ActiveX 版本(适用于 C++/Delphi/VB/PHP 等)。

您可以遍历每个页面的所有对象,选择那些是图像,并减小它们的大小。您有几种可能性:

  1. 设置较低的压缩率。
  2. 降采样(提取图像,将其调整为较低的分辨率,然后将其放回文件中)。
  3. 结合前两者。

以下是第一种选项的代码示例,使用 Amyuni PDF Creator .Net 的 C# 版本:

//open a pdf document
document.Open("c:\\temp\\myfile.pdf","");
IacPage page1 = document.GetPage (1);
Amyuni.PDFCreator.IacAttribute attribute = page1.AttributeByName ("Objects");
// listobj is an array list of graphic objects
System.Collections.ArrayList listobj = (System.Collections.ArrayList) attribute.Value;
foreach ( object pdfObj in listobj )
{
    if ((IacObjectType)pdfObj.AttributeByName("ObjectType").Value == IacObjectType.acObjectTypePicture)
    {
        if ((IacImageCompressionConstants)pdfObj.AttributeByName("Compression").Value == IacImageCompressionConstants.acCompressionJPegMedium)
            pdfObj.AttributeByName("Compression").Value = IacImageCompressionConstants.acCompressionJPegLow;

        if ((IacImageCompressionConstants)pdfObj.AttributeByName("Compression").Value == IacImageCompressionConstants.acCompressionJPegHigh)
            pdfObj.AttributeByName("Compression").Value = IacImageCompressionConstants.acCompressionJPegMedium;
        // (...)
    }
}

通常的免责声明适用


0
你可能想要尝试使用Docotic.Pdf库来完成你的任务。
下面是一段代码,它会对所有宽度或高度大于等于256的图像进行缩放。然后使用JPEG压缩将缩放后的图像编码,质量设置为65。
public static void RecompressToJpeg(string path, string outputPath)
{
    using (PdfDocument doc = new PdfDocument(path))
    {
        foreach (PdfImage image in doc.Images)
        {
            // image that is used as mask or image with attached mask are
            // not good candidates for recompression
            if (!image.IsMask && image.Mask == null && (image.Width >= 256 || image.Height >= 256))
                image.Scale(0.5, PdfImageCompression.Jpeg, 65);
        }

        doc.Save(outputPath);
    }
}

您也可以使用其中一个RecompressWithJpeg方法(或其他RecompressXXX方法)仅重新压缩图像而不改变其大小。
并且可以使用其中一个ResizeTo方法将图像调整为指定的宽度和高度。请注意,在后一种情况下,您需要考虑纵横比。
免责声明:我为该库的供应商工作。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接