SlidePages.vb
'' 
'' このコードは、DioDocs for PDF のサンプルの一部として提供されています。
'' © MESCIUS inc. All rights reserved.
'' 
Imports System.IO
Imports System.Drawing
Imports GrapeCity.Documents.Pdf
Imports GrapeCity.Documents.Text
Imports GrapeCity.Documents.Drawing
Imports GCTEXT = GrapeCity.Documents.Text
Imports GCDRAW = GrapeCity.Documents.Drawing

'' ディレクトリにあるすべての画像から「スライド」のページを作成します。
'' 
'' 重要:DsPdf 内で画像を複数回描画するとき(例えば、すべてのページのページヘッダの一部として
'' 同じ画像を描画するなど)、すべてのページで同じイメージオブジェクトを使用する場合は、
'' 自動的に辞書に追加され、ドキュメント全体で再利用されます。
'' そのため、必要になるたびにファイル(またはストリーム)から同じ画像を読み込むのではなく、
'' 画像を一度読み込んでイメージオブジェクトにキャッシュすることが常に望ましいです。
'' これは、DsPdf(Image、RawImage)で利用できるすべての画像形式に適用されます。
Public Class SlidePages
    Function CreatePDF(ByVal stream As Stream) As Integer
        Dim doc = New GcPdfDocument()
        '' キャプション用のフォントを取得します。
        Dim fnt = GCTEXT.Font.FromFile(Path.Combine("Resources", "Fonts", "segoeui.ttf"))
        '' GcPdfDocument.ImageOptions では、さまざまな画像関連の設定を制御できます。
        '' たとえば、JPEG の画質を規定の75%から引き下げ、ファイルサイズを小さくすることが可能です。
        doc.ImageOptions.JpegQuality = 50

        '' Resources/Images フォルダからすべての画像を読み込みます。
        Dim images = New List(Of Tuple(Of String, IImage))
        For Each fname In Directory.GetFiles(Path.Combine("Resources", "Images"), "*", SearchOption.AllDirectories)
            images.Add(Tuple.Create(Path.GetFileName(fname), Util.ImageFromFile(fname)))
        Next

        images.Shuffle()
        '' すべての画像をスライドシートとして 3x4 の格子状に 1/2 インチの余白で印刷します。
        Const margin = 36.0F
        Const rows = 4
        Const cols = 3
        Dim gapx = 72.0F / 4, gapy = gapx
        Dim sWidth = (doc.PageSize.Width - margin * 2 + gapx) / cols
        Dim sHeight = (doc.PageSize.Height - margin * 2 + gapy) / rows
        If sWidth > sHeight Then
            gapx += sWidth - sHeight
            sWidth = sHeight
        Else
            gapy += sHeight - sWidth
            sHeight = sWidth
        End If

        Const sMargin = 72.0F / 6
        '' 画像を指定された領域内の中心に配置するよう設定します。
        Dim ia = New ImageAlign(ImageAlignHorz.Center, ImageAlignVert.Center, True, True, True, False, False)
        '' 画像キャプションのテキスト書式。
        Dim tf = New TextFormat() With {.Font = fnt, .FontSize = sMargin * 0.65F}
        '' 挿入位置。
        Dim ip = New PointF(margin, margin)
        Dim g = doc.NewPage().Graphics
        For i = 0 To images.Count() - 1
            Dim rect = New RectangleF(ip, New SizeF(sWidth - gapx, sHeight - gapy))
            g.FillRectangle(rect, Color.LightGray)
            g.DrawRectangle(rect, Color.Black, 0.5F)
            rect.Inflate(-sMargin, -sMargin)
            '' DrawImage メソッドから(出力パラメータを介して)イメージが描画された実際の矩形を取得し、
            '' イメージの周りに細い境界線を正確に描くことができます
            '' (イメージがタイル化できるので、配列が必要です。この場合、複数の矩形が返されます)。
            Dim imageRect As RectangleF() = Nothing
            g.DrawImage(images(i).Item2, rect, Nothing, ia, imageRect)
            g.DrawRectangle(imageRect(0), Color.DarkGray, 1)
            '' スライドの下部余白に画像ファイル名をキャプションとして出力します。
            g.DrawString(Path.GetFileName(images(i).Item1), tf,
                New RectangleF(rect.X, rect.Bottom, rect.Width, sMargin),
                TextAlignment.Center, ParagraphAlignment.Near, False)
            ip.X += sWidth
            If ip.X + sWidth > doc.PageSize.Width AndAlso i < images.Count() - 1 Then
                ip.X = margin
                ip.Y += sHeight
                If ip.Y + sHeight > doc.PageSize.Height Then
                    g = doc.NewPage().Graphics
                    ip.Y = margin
                End If
            End If
        Next
        ''
        '' PDF ドキュメントを保存します。
        doc.Save(stream)
        '' PDF を保存した後に画像を廃棄します。
        images.ForEach(Sub(t_) t_.Item2.Dispose())
        Return doc.Pages.Count
    End Function
End Class