ObjectStreams.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;
using GCTEXT = GrapeCity.Documents.Text;
using GCDRAW = GrapeCity.Documents.Drawing;
namespace DsPdfWeb.Demos
{
// SavePdfOptions.UseObjectStreamsプロパティの使用方法について。
// PDFのサイズを縮小するデモです。
//
// サイズの削減は状況に応じて異なることに注意してください。
// ソースのPDFの実際の内容について説明します。
public class ObjectStreams
{
public int CreatePDF(Stream stream)
{
// 5 ページの最適化されていない PDF を作成します。
var tmpInput = MakeInputFile();
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.Save(tmpOutput, new SavePdfOptions(SaveMode.Default, PdfStreamHandling.MinimizeSize, UseObjectStreams.Multiple));
}
var fiOutput = new FileInfo(tmpOutput);
// 結果として得られる PDF の入力ファイルと出力ファイルのサイズを記録します。
var doc = new GcPdfDocument();
Common.Util.AddNote(String.Format(
"PDF を保存する際に UseObjectStreams.Multiple オプションを使用すると、ほとんどの場合、生成されるファイルサイズが削減され、" +
"場合によっては大幅に小さくなります。今回の例では、「大規模なドキュメント」サンプルによって生成されたPDFのサイズが {0:N0} バイトから " +
"{1:N0} バイトに減少しました。これは、品質の劣化やPDFの表示速度の低下なしに実現しています。\n" +
"UseObjectStreams.Single オプションを使用すると、さらに僅かに小さなPDFサイズを実現できますが、" +
"その代わりに PDFビューアでの表示速度が遅くなる可能性があります。\n" +
"これらの結果をローカル環境で再現するには、このサンプルをダウンロードして実行し、有効なライセンスキーを指定してください。\n" +
"(ライセンスキーがない場合、読み込みが 5 ページまでに制限され、サイズ削減の効果が十分に得られない可能性があります。)\n" +
"また、サンプルコードを修正して一時的な入力ファイルと出力ファイルを保持し、ファイルマネージャを使用してサイズを比較することもできます。",
fiInput.Length, fiOutput.Length),
doc.NewPage());
doc.Save(stream);
// 一時ファイルの削除
File.Delete(tmpInput);
File.Delete(tmpOutput);
return doc.Pages.Count;
}
static string MakeInputFile()
{
// 生成するページ数
const int N = Common.Util.LargeDocumentIterations;
var start = Common.Util.TimeNow();
var doc = new GcPdfDocument();
// テキストを保持/フォーマットするための TextLayout を準備します。
var tl = new TextLayout(72)
{
MaxWidth = doc.PageSize.Width,
MaxHeight = doc.PageSize.Height,
MarginAll = 72,
FirstLineIndent = 36,
};
tl.DefaultFormat.Font = StandardFonts.Times;
tl.DefaultFormat.FontSize = 12;
// ドキュメントを生成します。
for (int pageIdx = 0; pageIdx < N; ++pageIdx)
{
tl.Append(Common.Util.LoremIpsum(1));
tl.PerformLayout(true);
doc.NewPage().Graphics.DrawTextLayout(tl, PointF.Empty);
tl.Clear();
}
// タイトル ページを挿入します (StartDoc/EndDoc を使用している場合は実行できません)。
tl.FirstLineIndent = 0;
var fnt = GCTEXT.Font.FromFile(Path.Combine("Resources", "Fonts", "yumin.ttf"));
var tf0 = new TextFormat() { Font = fnt, FontSize = 24, FontBold = true };
tl.Append(string.Format("Large Document\n{0} Pages of Lorem Ipsum\n\n", N), tf0);
var tf1 = new TextFormat(tf0) { FontSize = 14, FontItalic = true };
tl.Append(string.Format("Generated on {0} in {1:m\\m\\ s\\s\\ fff\\m\\s}.", Common.Util.TimeNow().ToString("R"), Common.Util.TimeNow() - start), tf1);
tl.TextAlignment = TextAlignment.Center;
tl.PerformLayout(true);
doc.Pages.Insert(0).Graphics.DrawTextLayout(tl, PointF.Empty);
// 結果の PDF を UseObjectStreams.None (デフォルト) を使用して一時ファイルに保存します。
var outFn = Path.GetTempFileName();
doc.Save(outFn, new SavePdfOptions(SaveMode.Default, PdfStreamHandling.Copy, UseObjectStreams.None));
return outFn;
}
}
}