C#でPDFサイズを最適化、圧縮、または削減する

PDFドキュメントには、時折追加データが含まれることがあります。PDFファイルのサイズを削減することで、ネットワーク転送とストレージを最適化できます。これは、ウェブページへの公開、ソーシャルネットワークでの共有、電子メールでの送信、またはストレージへのアーカイブに特に便利です。PDFを最適化するために、いくつかの技術を使用できます:

  • オンラインブラウジング用にページコンテンツを最適化します。
  • すべての画像を縮小または圧縮します。
  • ページコンテンツの再利用を可能にします。
  • 重複ストリームをマージします。
  • フォントをアンエンベッドします。
  • 未使用のオブジェクトを削除します。
  • フラット化されたフォームフィールドを削除します。
  • 注釈を削除またはフラット化します。

ウェブ用にPDFドキュメントを最適化する

最適化、またはウェブ用の線形化は、PDFファイルをウェブブラウザでオンラインブラウジングに適したものにするプロセスを指します。ウェブ表示用にファイルを最適化するには:

  1. Documentオブジェクトで入力ドキュメントを開きます。
  2. Optimizeメソッドを使用します。
  3. Saveメソッドを使用して最適化されたドキュメントを保存します。

以下のコードスニペットは、Aspose.PDF.Drawingライブラリでも機能します。

以下のコードスニペットは、ウェブ用にPDFドキュメントを最適化する方法を示しています。

// For complete examples and data files, visit https://github.com/aspose-pdf/Aspose.PDF-for-.NET
private static void OptimizeDocument()
{
    // The path to the documents directory
    var dataDir = RunExamples.GetDataDir_AsposePdf_WorkingDocuments();

    // Open PDF document
    using (var document = new Aspose.Pdf.Document(dataDir + "OptimizeDocument.pdf"))
    {
        // Optimize for web
        document.Optimize();

        // Save PDF document
        document.Save(dataDir + "OptimizeDocument_out.pdf");
    }
}

PDFサイズを削減する

OptimizeResources()メソッドを使用すると、不要な情報を取り除くことでドキュメントサイズを削減できます。デフォルトでは、このメソッドは次のように機能します:

  • ドキュメントページで使用されていないリソースが削除されます。
  • 同じリソースが1つのオブジェクトに結合されます。
  • 未使用のオブジェクトが削除されます。

以下のスニペットはその例です。ただし、このメソッドはドキュメントの縮小を保証するものではありません。

// For complete examples and data files, visit https://github.com/aspose-pdf/Aspose.PDF-for-.NET
private static void ShrinkDocument()
{
    // The path to the documents directory
    var dataDir = RunExamples.GetDataDir_AsposePdf_WorkingDocuments();

    // Open PDF document
    using (var document = new Aspose.Pdf.Document(dataDir + "ShrinkDocument.pdf"))
    {
        // Optimize PDF document. Note, though, that this method cannot guarantee document shrinking
        document.OptimizeResources();

        // Save PDF document
        document.Save(dataDir + "ShrinkDocument_out.pdf");
    }
}

最適化戦略の管理

最適化戦略をカスタマイズすることもできます。現在、OptimizeResources()メソッドは5つの技術を使用しています。これらの技術は、OptimizationOptionsパラメータを使用してOptimizeResources()メソッドで適用できます。

すべての画像を縮小または圧縮する

画像を扱う方法は2つあります:画像の品質を低下させることと、解像度を変更することです。いずれの場合でも、ImageCompressionOptionsを適用する必要があります。以下の例では、ImageQualityを50に設定して画像を縮小します。

ImageQualityはJPEG品質と同様に機能し、値0が最低、値100が最高です。

// For complete examples and data files, visit https://github.com/aspose-pdf/Aspose.PDF-for-.NET
private static void ShrinkImage()
{
    // The path to the documents directory
    var dataDir = RunExamples.GetDataDir_AsposePdf_Images();

    // Open PDF document
    using (var document = new Aspose.Pdf.Document(dataDir + "Shrinkimage.pdf"))
    {
        // Initialize OptimizationOptions
        var optimizeOptions = new Aspose.Pdf.Optimization.OptimizationOptions();

        // Set CompressImages option
        // If this flag is set to true images will be compressed in the document
        optimizeOptions.ImageCompressionOptions.CompressImages = true;

        // Set ImageQuality option
        // Specifies level of image compression when CompressImages flag is used
        optimizeOptions.ImageCompressionOptions.ImageQuality = 50;

        // Optimize PDF document using OptimizationOptions
        document.OptimizeResources(optimizeOptions);

        // Save PDF document
        document.Save(dataDir + "Shrinkimage_out.pdf");
    }
}

もう1つの方法は、解像度を下げて画像のサイズを変更することです。この場合、ResizeImagesをtrueに設定し、MaxResolutionを適切な値に設定する必要があります。

// For complete examples and data files, visit https://github.com/aspose-pdf/Aspose.PDF-for-.NET
private static void ResizeImages()
{
    // The path to the documents directory
    var dataDir = RunExamples.GetDataDir_AsposePdf_Images();

    // Open PDF document
    using (var document = new Aspose.Pdf.Document(dataDir + "ResizeImage.pdf"))
    {
        // Initialize OptimizationOptions
        var optimizeOptions = new Aspose.Pdf.Optimization.OptimizationOptions();

        // Set CompressImages option
        // If this flag is set to true images will be compressed in the document
        optimizeOptions.ImageCompressionOptions.CompressImages = true;

        // Set ImageQuality option
        // Specifies level of image compression when CompressImages flag is used
        optimizeOptions.ImageCompressionOptions.ImageQuality = 75;

        // Set ResizeImage option
        // If this flag set to true and CompressImages is true images will be resized if image resolution is greater then specified MaxResolution parameter
        optimizeOptions.ImageCompressionOptions.ResizeImages = true;

        // Set MaxResolution option
        // Specifies maximum resolution of images. If image has higher resolition it will be scaled
        optimizeOptions.ImageCompressionOptions.MaxResolution = 300;

        // Optimize PDF document using OptimizationOptions
        document.OptimizeResources(optimizeOptions);

        // Save PDF document
        document.Save(dataDir + "ResizeImages_out.pdf");
    }
}

もう1つの重要な問題は実行時間です。しかし、再び、この設定も管理できます。現在、2つのアルゴリズム - StandardとFastを使用できます。実行時間を制御するには、Versionプロパティを設定する必要があります。以下のスニペットはFastアルゴリズムを示しています:

// For complete examples and data files, visit https://github.com/aspose-pdf/Aspose.PDF-for-.NET
private static void FastShrinkImages()
{
    // Initialize Time
    var time = DateTime.Now.Ticks;

    // The path to the documents directory
    var dataDir = RunExamples.GetDataDir_AsposePdf_Images();

    // Open PDF document
    using (var document = new Aspose.Pdf.Document(dataDir + "Shrinkimage.pdf"))
    {
        // Initialize OptimizationOptions
        var optimizeOptions = new Aspose.Pdf.Optimization.OptimizationOptions();

        // Set CompressImages option
        // If this flag is set to true images will be compressed in the document
        optimizeOptions.ImageCompressionOptions.CompressImages = true;

        // Set ImageQuality option
        // Specifies level of image compression when CompressImages flag is used
        optimizeOptions.ImageCompressionOptions.ImageQuality = 75;

        // Set Image Compression Version to fast
        // Version of compression algorithm. Possible values are:
        // 1. standard compression
        // 2. fast (improved compression which is faster then standard but may be applicable not for all images)
        // 3. mixed (standard compression is applied to images which can not be compressed by faster algorithm, 
        // this may give best compression but more slow then "fast" algorithm. Version "Fast" is not applicable for 
        // resizing images (standard method will be used). Default is "Standard"
        optimizeOptions.ImageCompressionOptions.Version = Aspose.Pdf.Optimization.ImageCompressionVersion.Fast;

        // Optimize PDF document using OptimizationOptions
        document.OptimizeResources(optimizeOptions);

        // Save PDF document
        document.Save(dataDir + "FastShrinkImages_out.pdf");
    }

    // Output the time taken for the operation
    Console.WriteLine("Ticks: {0}", DateTime.Now.Ticks - time);
}

未使用のオブジェクトを削除する

PDFドキュメントには、他のオブジェクトから参照されていないPDFオブジェクトが含まれていることがあります。これは、たとえば、ページがドキュメントページツリーから削除されたが、ページオブジェクト自体は削除されていない場合に発生することがあります。これらのオブジェクトを削除してもドキュメントが無効になることはありませんが、むしろサイズが縮小されます。

// For complete examples and data files, visit https://github.com/aspose-pdf/Aspose.PDF-for-.NET
private static void OptimizeDocument()
{
    // The path to the documents directory
    var dataDir = RunExamples.GetDataDir_AsposePdf_WorkingDocuments();

    // Open PDF document
    using (var document = new Aspose.Pdf.Document(dataDir + "OptimizeDocument.pdf"))
    {
        // Set RemoveUsedObject option
        var optimizeOptions = new Aspose.Pdf.Optimization.OptimizationOptions
        {
            RemoveUnusedObjects = true
        };
        
        // Optimize PDF document using OptimizationOptions
        document.OptimizeResources(optimizeOptions);

        // Save PDF document
        document.Save(dataDir + "OptimizeDocument_out.pdf");
    }
}

未使用のストリームを削除する

時々、ドキュメントには未使用のリソースストリームが含まれています。これらのストリームは「未使用のオブジェクト」ではなく、ページリソース辞書から参照されています。したがって、「未使用のオブジェクトを削除する」メソッドでは削除されません。しかし、これらのストリームはページコンテンツでは決して使用されません。これは、画像がページから削除されたが、ページリソースからは削除されていない場合に発生することがあります。また、この状況は、ページがドキュメントから抽出され、ドキュメントページが「共通」リソース、つまり同じResourcesオブジェクトを持つ場合によく発生します。リソースストリームが使用されているかどうかを判断するためにページコンテンツが分析されます。未使用のストリームが削除されます。これにより、ドキュメントサイズが減少することがあります。この技術の使用は前のステップと似ています:

// For complete examples and data files, visit https://github.com/aspose-pdf/Aspose.PDF-for-.NET
private static void OptimizePdfDocument()
{
    // The path to the documents directory
    var dataDir = RunExamples.GetDataDir_AsposePdf_WorkingDocuments();

    // Open PDF document
    using (var document = new Aspose.Pdf.Document(dataDir + "OptimizeDocument.pdf"))
    {
        // Set RemoveUsedStreams option
        var optimizeOptions = new Aspose.Pdf.Optimization.OptimizationOptions
        {
            RemoveUnusedStreams = true
        };

        // Optimize PDF document using OptimizationOptions
        document.OptimizeResources(optimizeOptions);

        // Save PDF document
        document.Save(dataDir + "OptimizeDocument_out.pdf");
    }
}

重複ストリームをリンクする

一部のドキュメントには、同一のリソースストリーム(たとえば画像)が複数含まれていることがあります。これは、たとえば、ドキュメントが自分自身と連結された場合に発生することがあります。出力ドキュメントには、同じリソースストリームの2つの独立したコピーが含まれています。すべてのリソースストリームを分析し、比較します。ストリームが重複している場合、それらはマージされ、つまり1つのコピーだけが残ります。参照は適切に変更され、オブジェクトのコピーは削除されます。場合によっては、これによりドキュメントサイズが減少します。

// For complete examples and data files, visit https://github.com/aspose-pdf/Aspose.PDF-for-.NET
private static void OptimizePdfDocumentWithLinkDuplicateStreams()
{
    // The path to the documents directory
    var dataDir = RunExamples.GetDataDir_AsposePdf_WorkingDocuments();

    // Open PDF document
    using (var document = new Aspose.Pdf.Document(dataDir + "OptimizeDocument.pdf"))
    {
        // Set LinkDuplicateStreams option
        var optimizeOptions = new Aspose.Pdf.Optimization.OptimizationOptions
        {
            LinkDuplicateStreams = true
        };

        // Optimize PDF document using OptimizationOptions
        document.OptimizeResources(optimizeOptions);

        // Save PDF document
        document.Save(dataDir + "OptimizeDocument_out.pdf");
    }
}

さらに、AllowReusePageContent設定を使用できます。このプロパティがtrueに設定されている場合、同一ページの最適化時にページコンテンツが再利用されます。

// For complete examples and data files, visit https://github.com/aspose-pdf/Aspose.PDF-for-.NET
private static void OptimizePdfDocumentWithReusePageContent()
{
    // The path to the documents directory
    var dataDir = RunExamples.GetDataDir_AsposePdf_WorkingDocuments();

    // Open PDF document
    using (var document = new Aspose.Pdf.Document(dataDir + "OptimizeDocument.pdf"))
    {
        // Set AllowReusePageContent option
        var optimizeOptions = new Aspose.Pdf.Optimization.OptimizationOptions
        {
            AllowReusePageContent = true
        };

        Console.WriteLine("Start");

        // Optimize PDF document using OptimizationOptions
        document.OptimizeResources(optimizeOptions);

        // Save PDF document
        document.Save(dataDir + "OptimizeDocument_out.pdf");
    }

    Console.WriteLine("Finished");

    // Calculate and display file sizes
    var fi1 = new FileInfo(dataDir + "OptimizeDocument.pdf");
    var fi2 = new FileInfo(dataDir + "OptimizeDocument_out.pdf");
    Console.WriteLine("Original file size: {0}. Reduced file size: {1}", fi1.Length, fi2.Length);
}

フォントのアンエンベッド

ドキュメントが埋め込まれたフォントを使用している場合、それはすべてのフォントデータがドキュメントに保存されていることを意味します。利点は、ユーザーのマシンにフォントがインストールされているかどうかに関係なく、ドキュメントが表示可能であることです。しかし、フォントを埋め込むとドキュメントが大きくなります。フォントのアンエンベッドメソッドは、すべての埋め込まれたフォントを削除します。したがって、ドキュメントサイズは減少しますが、正しいフォントがインストールされていない場合、ドキュメント自体が読めなくなる可能性があります。

// For complete examples and data files, visit https://github.com/aspose-pdf/Aspose.PDF-for-.NET
private static void OptimizePdfDocumentWithUnembedFonts()
{
    // The path to the documents directory
    var dataDir = RunExamples.GetDataDir_AsposePdf_WorkingDocuments();

    // Open PDF document
    using (var document = new Aspose.Pdf.Document(dataDir + "OptimizeDocument.pdf"))
    {
        // Set UnembedFonts option
        var optimizeOptions = new Aspose.Pdf.Optimization.OptimizationOptions
        {
            UnembedFonts = true
        };

        Console.WriteLine("Start");

        // Optimize PDF document using OptimizationOptions
        document.OptimizeResources(optimizeOptions);

        // Save PDF document
        document.Save(dataDir + "OptimizeDocument_out.pdf");	
    }
	
    Console.WriteLine("Finished");

    // Calculate and display file sizes
    var fi1 = new FileInfo(dataDir + "OptimizeDocument.pdf");
    var fi2 = new FileInfo(dataDir + "OptimizeDocument_out.pdf");
    Console.WriteLine("Original file size: {0}. Reduced file size: {1}", fi1.Length, fi2.Length);
}

最適化リソースは、これらのメソッドをドキュメントに適用します。これらのメソッドのいずれかが適用されると、ドキュメントサイズはおそらく減少します。これらのメソッドが適用されない場合、ドキュメントサイズは変わらないことは明らかです。

PDFドキュメントサイズを削減するための追加方法

注釈を削除またはフラット化する

注釈は不要な場合に削除できます。必要だが追加の編集を必要としない場合は、フラット化できます。これらの技術の両方がファイルサイズを削減します。

// For complete examples and data files, visit https://github.com/aspose-pdf/Aspose.PDF-for-.NET
private static void FlattenAnnotationsInPdfDocument()
{
    // The path to the documents directory
    var dataDir = RunExamples.GetDataDir_AsposePdf_WorkingDocuments();

    // Open PDF document
    using (var document = new Aspose.Pdf.Document(dataDir + "OptimizeDocument.pdf"))
    {
        // Flatten annotations
        foreach (var page in document.Pages)
        {
            foreach (var annotation in page.Annotations)
            {
                annotation.Flatten();
            }
        }

        // Save PDF document
        document.Save(dataDir + "OptimizeDocument_out.pdf");
    }
}

フォームフィールドを削除する

PDFドキュメントにAcroFormsが含まれている場合、フォームフィールドをフラット化することでファイルサイズを削減できるかもしれません。

// For complete examples and data files, visit https://github.com/aspose-pdf/Aspose.PDF-for-.NET
private static void FlattenPdfForms()
{
    // The path to the documents directory
    var dataDir = RunExamples.GetDataDir_AsposePdf_Forms();

    // Load source PDF form
    using (var document = new Aspose.Pdf.Document(dataDir + "input.pdf"))
    {
        // Flatten Forms
        if (document.Form.Fields.Lenght > 0)
        {
            foreach (var item in document.Form.Fields)
            {
                item.Flatten();
            }
        }

        // Save PDF document
        document.Save(dataDir + "FlattenForms_out.pdf");
    }
}

PDFをRGBカラースペースからグレースケールに変換する

PDFファイルは、テキスト、画像、添付ファイル、注釈、グラフ、およびその他のオブジェクトで構成されています。PDFをRGBカラースペースからグレースケールに変換する必要がある場合があります。これにより、これらのPDFファイルを印刷する際に速度が向上します。また、ファイルがグレースケールに変換されると、ドキュメントサイズも削減されますが、ドキュメントの品質が低下する可能性もあります。この機能は現在、Adobe AcrobatのPre-Flight機能によってサポートされていますが、Office自動化について話すと、Aspose.PDFはドキュメント操作のための究極のソリューションです。この要件を達成するために、以下のコードスニペットを使用できます。

// For complete examples and data files, visit https://github.com/aspose-pdf/Aspose.PDF-for-.NET
private static void ConvertRgbToGrayScale()
{
    // The path to the documents directory
    var dataDir = RunExamples.GetDataDir_AsposePdf_WorkingDocuments();

    // Open PDF document
    using (var document = new Aspose.Pdf.Document(dataDir + "input.pdf"))
    {
        // Create RGB to DeviceGray conversion strategy
        var strategy = new Aspose.Pdf.RgbToDeviceGrayConversionStrategy();

        // Iterate through each page
        for (int idxPage = 1; idxPage <= document.Pages.Count; idxPage++)
        {
            // Get instance of particular page inside PDF
            var page = document.Pages[idxPage];

            // Convert the RGB colorspace image to GrayScale colorspace
            strategy.Convert(page);
        }

        // Save PDF document
        document.Save(dataDir + "TestGray_out.pdf");
    }
}

FlateDecode圧縮

Aspose.PDF for .NETはPDF最適化機能のためのFlateDecode圧縮をサポートしています。以下のコードスニペットは、FlateDecode圧縮で画像を保存するための最適化オプションの使用方法を示しています:

// For complete examples and data files, please go to https://github.com/aspose-pdf/Aspose.PDF-for-.NET
private static void OptimizeDocumentImagesWithFlateCompression()
{
    // The path to the documents directory
    var dataDir = RunExamples.GetDataDir_AsposePdf_Images();

    // Open PDF document
    using (var document = new Aspose.Pdf.Document(dataDir + "AddImage.pdf"))
    {
        // Initialize OptimizationOptions
        var optimizationOptions = new Aspose.Pdf.Optimization.OptimizationOptions();

        // To optimize images using FlateDecode compression, set optimization options to Flate
        optimizationOptions.ImageCompressionOptions.Encoding = Aspose.Pdf.Optimization.ImageEncoding.Flate;

        // Set optimization options
        document.OptimizeResources(optimizationOptions);

        // Save PDF document
        document.Save(dataDir + "OptimizeDocumentImagesWithFlateCompression_out.pdf");
    }
}

XImageCollectionに画像を保存する

Aspose.PDF for .NETは、FlateDecode圧縮で新しい画像をXImageCollectionに保存する機能を提供します。このオプションを有効にするには、ImageFilterType.Flateフラグを使用できます。以下のコードスニペットは、この機能の使用方法を示しています:

// For complete examples and data files, please go to https://github.com/aspose-pdf/Aspose.PDF-for-.NET
private static void AddImageToPdfWithFlateCompression()
{
    // The path to the documents directory
    var dataDir = RunExamples.GetDataDir_AsposePdf_Images();

    // Create PDF document
    using (var document = new Aspose.Pdf.Document())
    {
        // Add page
        var page = document.Pages.Add();

        // Open the image file stream
        using (var imageStream = new FileStream(dataDir + "aspose-logo.jpg", FileMode.Open))
        {
            // Add the image to the page resources with Flate compression
            page.Resources.Images.Add(imageStream, Aspose.Pdf.ImageFilterType.Flate);
        }

        // Get the added image
        var ximage = page.Resources.Images[page.Resources.Images.Count];

        // Save the current graphics state
        page.Contents.Add(new Aspose.Pdf.Operators.GSave());

        // Set coordinates for the image placement
        int lowerLeftX = 0;
        int lowerLeftY = 0;
        int upperRightX = 600;
        int upperRightY = 600;

        var rectangle = new Aspose.Pdf.Rectangle(lowerLeftX, lowerLeftY, upperRightX, upperRightY);
        var matrix = new Aspose.Pdf.Matrix(new double[]
        {
            rectangle.URX - rectangle.LLX, 0, 0, rectangle.URY - rectangle.LLY, rectangle.LLX, rectangle.LLY
        });

        // Use ConcatenateMatrix operator to define how the image must be placed
        page.Contents.Add(new Aspose.Pdf.Operators.ConcatenateMatrix(matrix));
        page.Contents.Add(new Aspose.Pdf.Operators.Do(ximage.Name));

        // Restore the graphics state
        page.Contents.Add(new Aspose.Pdf.Operators.GRestore());

        // Save the document
        document.Save(dataDir + "AddImageToPdfWithFlateCompression_out.pdf");
    }
}