OptimizeFonts.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.OptimizeFonts() メソッドを使用して、重複するフォントを統合し、
// 使用されていない埋め込みフォントを削除することにより、PDF のサイズを縮小する方法を紹介します。
//
// サンプルでは、PDF の最初の5ページを抽出し、それらのページを1つの新しいドキュメントに結合しています。
// 各ページには独自のフォントが埋め込まれているため、作成された PDF には不要なフォントデータが含まれ、
// ファイルサイズが過大になってしまいます。
// サンプルでは、結合された PDF のサイズを記録し、その PDF に対して OptimizeFonts() を実行し、
// 最適化後の PDF のサイズも記録します。この結果は、サンプルで生成した PDF に出力されており、
// OptimizeFonts() を実行した効果を確認いただけます。
//
// なお、このサンプルで最適化される PDF は結果がわかりやすくなるよう多少工夫されていますが、
// 実際のアプリケーションでも同様の PDF を処理することが考えられます。
// OptimizeFonts() メソッドは、そのような PDF のサイズを(時には大幅に)減少させることができます。
// ただ、実際の結果は異なることがあります。
public class OptimizeFonts
{
public int CreatePDF(Stream stream)
{
// 5ページの最適化されていない PDF を作成します。
var srcFn = Path.Combine("Resources", "PDFs", "CompleteJavaScriptBook.pdf");
var tmpInput = MakeInputFile(srcFn);
var fiInput = new FileInfo(tmpInput);
// 新しい PDF を作成し、そこに上で作成した PDF を読み込み、最適化します。
var tmpOutput = Path.GetTempFileName();
var tmpDoc = new GcPdfDocument();
using (var fs = File.OpenRead(tmpInput))
{
tmpDoc.Load(fs);
// デフォルトでは、GcPdfDocument は PDF を保存するときに CompressionLevel.Fastest を使用します。
// PDF のサイズを重視するのであれば、最適な圧縮を行うべきです。
tmpDoc.CompressionLevel = CompressionLevel.Optimal;
tmpDoc.OptimizeFonts();
tmpDoc.Save(tmpOutput);
}
var fiOutput = new FileInfo(tmpOutput);
// 結果の PDF に最適化前と最適化後のファイルサイズを記録します。
var doc = new GcPdfDocument();
Common.Util.AddNote(String.Format(
"GcPdfDocument.OptimizeFonts() メソッドを使用して、重複するフォントを統合し、使用されていない埋め込みフォントを削除することにより、" +
"5ページの PDF のサイズを {0:N0} バイトから {1:N0} バイトに縮小できました。\n" +
"この結果をローカルで再現するには、このサンプルをダウンロードして実行してください。また、サンプルコードを修正して、最適化されていないファイルと" +
"最適化されたファイルを保存し、ファイルマネージャーを使用してそのサイズを比較することもできます。", fiInput.Length, fiOutput.Length),
doc.NewPage());
doc.Save(stream);
// クリーンアップを行います。
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ページから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);
}
// 5つの PDF を1つの PDF に結合します。
var doc = new GcPdfDocument();
foreach (var d in docs)
doc.MergeWithDocument(d);
// 出来上がった PDF を一時ファイルに保存します。
var outFn = Path.GetTempFileName();
doc.Save(outFn);
return outFn;
}
}
}