OptimizePDF.cs
//
// このコードは、DioDocs for PDF のサンプルの一部として提供されています。
// © MESCIUS inc. All rights reserved.
//
using System;
using System.IO;
using System.IO.Compression;
using System.Drawing;
using System.Collections.Generic;
using GrapeCity.Documents.Pdf;
using GrapeCity.Documents.Text;
using GrapeCity.Documents.Common;
namespace DsPdfWeb.Demos
{
// GcPdfDocument.Optimize() メソッドを使用して、
// PDF のサイズを削減する方法を示します。
// 最適化手法の詳細については、OptimizeDocumentOptions クラスを参照してください。
//
// このサンプルでは、 最初に最適化を行っていない PDF の先頭 5 ページを
// 新しいドキュメントに結合し、そのサイズを記録します。
// 次に、その PDF に対して Optimize() を実行して最適化を行い、
// 再度 PDF のサイズを記録します。
// 最後に、最適化前と最適化後のPDFサイズを、
// このサンプルが生成する PDF 内に出力します。
// 「埋め込みフォントの削除」は、環境によってはドキュメントが正しく
// 表示されなくなる可能性があるため、
// RemoveEmbeddedFonts = false に設定して無効化しています。
//
// 最適化に関しては、 OptimizeFontsとRemoveDuplicateImagesも併せてご覧ください。
public class OptimizePDF
{
public int CreatePDF(Stream stream)
{
// 最適化をしていないPDFを読み込みます。
var srcFn = Path.Combine("Resources", "PDFs", "CompleteJavaScriptBook.pdf");
// テスト用に、上記のPDFの最初の5ページだけを使ったPDFを作成します。
var tmpInput = MakeInputFile(srcFn);
var fiInput = new FileInfo(tmpInput);
// 最適化用に、さらに新しいPDFを作成し、上記PDFを読み込みます。
// このPDFに対して最適化を実行します。
var tmpOutput = Path.GetTempFileName();
var tmpDoc = new GcPdfDocument();
using (var fs = File.OpenRead(tmpInput))
{
tmpDoc.Load(fs);
var odo = new OptimizeDocumentOptions();
// ファイルサイズが一番小さくなるよう、全ての処理を実行します。
odo.SetForMinimumSize();
// 埋め込みフォントは削除しないよう設定します。
odo.RemoveEmbeddedFonts = false;
tmpDoc.Optimize(tmpOutput, odo);
}
var fiOutput = new FileInfo(tmpOutput);
// 結果のPDFに入力ファイルと出力ファイルのサイズを記録しています。
var doc = new GcPdfDocument();
Common.Util.AddNote(String.Format(
"GcPdfDocument.Optimize() メソッドを使用することで、PDFサイズを {0:N0}バイト から {1:N0}バイト に削減できました。" +
"これは、SetForMinimumSizeメソッドを利用して、複数の最適化手法を適用したためです。\n" +
"同じ結果をローカル環境で再現したい場合は、このサンプルをダウンロードして実行してください。" +
"ローカル環境では最適化前と最適化後の両PDFファイルを、エクスプローラなどで比較できます。"
, fiInput.Length, fiOutput.Length),
doc.NewPage());
doc.Save(stream);
// クリーンアップ処理を行います。
// (デバッグしたい場合は、一時ファイルを削除せず、拡張子を .pdf に変更することで中身を確認できます。
// 以下の ChangeExtension を使った 2 行を有効にし、クリーンアップを無効にしてください。)
// File.Move(tmpInput, Path.ChangeExtension(tmpInput, ".pdf"), true);
// File.Move(tmpOutput, Path.ChangeExtension(tmpOutput, ".pdf"), true);
File.Delete(tmpInput);
File.Delete(tmpOutput);
return doc.Pages.Count;
}
static string MakeInputFile(string inFn)
{
var indoc = new GcPdfDocument();
using var fs = File.OpenRead(inFn);
indoc.Load(fs);
// 読み込んだPDFの最初の5ページを、新しいPDFに追加します。
var pageCount = 5;
var docs = new List<GcPdfDocument>(pageCount);
for (int i = 0; i < pageCount; ++i)
{
var outdoc = new GcPdfDocument();
outdoc.MergeWithDocument(indoc, new MergeDocumentOptions() { PagesRange = new OutputRange(i + 1, i + 1) });
docs.Add(outdoc);
}
var doc = new GcPdfDocument();
foreach (var d in docs)
doc.MergeWithDocument(d);
// 新しく作成したPDFを一時ファイルに保存して、そのファイル名を返します。
var outFn = Path.GetTempFileName();
doc.Save(outFn);
return outFn;
}
}
}