Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PDF lossy compression

I'm looking for a library or command-line program that can compress PDFs.

Compression speed and file size are very important.

The PDFs are full of very large print-quality images.

Adobe Acrobat does high-quality, fast compression but does not allow "reduced size pdfs" to be saved through a programmatic interface.

Ghostscript does high-quality compression be takes way too long (minutes).

like image 340
user1359680 Avatar asked Nov 13 '22 20:11

user1359680


1 Answers

If a commercial library is an option, you could give Amyuni PDF Creator a try. There is .net version (C#/VB.Net etc) and an ActiveX version (for C++/Delphi/VB/PHP etc).

You can iterate through all the objects of each page, pick those who are images, and reduce their size. You have several possibilities there:

  1. Setting a lower compression rate.
  2. Down-sampling (extracting the image, re-sizing it to a lower resolution, and putting it back in your file)
  3. Combining the previous two.

Here is how the code would look like for the first option, in C#, using Amyuni PDF Creator .Net:

//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;
        // (...)
    }
}

usual disclaimer applies

like image 100
yms Avatar answered Jan 04 '23 02:01

yms