SlidePages.vb
''
'' This code is part of GrapeCity Documents for PDF samples.
'' Copyright (c) GrapeCity, Inc. All rights reserved.
''
Imports System.IO
Imports System.Drawing
Imports GrapeCity.Documents.Pdf
Imports GrapeCity.Documents.Text
Imports GrapeCity.Documents.Drawing

'' Creates pages of 'slides' from all images found in a directory.
''
'' IMPORTANT NOTE: When you render an image in GcPdf multiple times (e.g. rendering
'' the same image as part of a page header on all pages), it will automatically be
'' added to a dictionary and reused throughout the document, provided you use
'' the same image object on all pages. So rather than loading the same image from
'' file (or stream) each time it is needed, it is always preferable to load the image
'' once and cache it in an image object. This applies to all image types available in
'' GcPdf (Image, RawImage, ImageWrapper).
Public Class SlidePages
    Function CreatePDF(ByVal stream As Stream) As Integer
        Dim doc = New GcPdfDocument()
        '' Get a font for captions:
        Dim fnt = Font.FromFile(Path.Combine("Resources", "Fonts", "segoeui.ttf"))
        '' GcPdfDocument.ImageOptions allow to control various image-related settings.
        '' In particular, we can lower the JPEG quality from the default 75% to reduce the file size:
        doc.ImageOptions.JpegQuality = 50

        '' Load all images from the Resources/Images folder:
        Dim images = New List(Of Tuple(Of String, Image))
        For Each fname In Directory.GetFiles(Path.Combine("Resources", "Images"), "*", SearchOption.AllDirectories)
            images.Add(Tuple.Create(Of String, Image)(Path.GetFileName(fname), Util.ImageFromFile(fname)))
        Next

        images.Shuffle()
        '' Print all images as slide sheets in a 3x4 grid with 1/2" margins all around:
        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
        '' Set up image alignment that would center images within the specified area:
        Dim ia = New ImageAlign(ImageAlignHorz.Center, ImageAlignVert.Center, True, True, True, False, False)
        '' Text format for image captions:
        Dim tf = New TextFormat() With {.Font = fnt, .FontSize = sMargin * 0.65F}
        '' Insertion point:
        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)
            '' We get the actual rectangle where the image was drawn from the DrawImage method
            '' (via an output parameter) so that we can draw a thin border exactly around the image
            '' (an array is required as the image can be tiled, in which case multiple rectangles
            '' will be returned):
            Dim imageRect As RectangleF() = Nothing
            g.DrawImage(images(i).Item2, rect, Nothing, ia, imageRect)
            g.DrawRectangle(imageRect(0), Color.DarkGray, 1)
            '' Print image file name as caption in the bottom slide margin:
            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
        ''
        '' Done:
        doc.Save(stream)
        '' Dispose images (can be done only after saving the document):
        images.ForEach(Sub(t_) t_.Item2.Dispose())
        Return doc.Pages.Count
    End Function
End Class