ImageLinks.vb
'' 完毕:
Imports System.IO
Imports System.Drawing
Imports System.Numerics
Imports GrapeCity.Documents.Pdf
Imports GrapeCity.Documents.Text
Imports GrapeCity.Documents.Drawing
Imports GrapeCity.Documents.Pdf.Annotations
Imports GrapeCity.Documents.Pdf.Actions
Imports GCTEXT = GrapeCity.Documents.Text
Imports GCDRAW = GrapeCity.Documents.Drawing

'' 此示例加载目录中找到的所有图像,然后渲染每个图像
'' 在 PDF 的单独页面上以最大可能的尺寸。
'' 最后,它插入链接到大图像的图像缩略图目录
'' 到文档中。
'' 另请参阅SlidePages。
Public Class ImageLinks
    Private Class ImageInfo
        Public Property Name As String
        Public Property Image As IImage
        Public Property PageIdx As Integer
    End Class

    Function CreatePDF(ByVal stream As Stream) As Integer
        Dim doc = New GcPdfDocument()
        Dim fnt = GCTEXT.Font.FromFile(Path.Combine("Resources", "Fonts", "segoeui.ttf"))
        '' 四周 1/4 英寸页边距:
        Const margin = 36.0F

        '' 从 Resources/Images 文件夹加载所有图像:
        Dim imageInfos As New List(Of ImageInfo)
        For Each fname In Directory.GetFiles(Path.Combine("Resources", "Images"), "*", SearchOption.AllDirectories)
            imageInfos.Add(New ImageInfo() With {.Name = Path.GetFileName(fname), .Image = Util.ImageFromFile(fname)})
        Next
        imageInfos.Shuffle()
        '' 设置图像对齐方式,使图像水平居中并垂直顶部对齐:
        Dim ia = New ImageAlign(ImageAlignHorz.Center, ImageAlignVert.Top, True, True, True, False, False)
        '' 全尺寸图像的图像矩形 - 整个页面:
        Dim rBig = New RectangleF(margin, margin, doc.PageSize.Width - margin * 2, doc.PageSize.Height - margin * 2)
        '' 将所有图像渲染为全尺寸,每页一张图像:
        For i = 0 To imageInfos.Count - 1
            Dim g = doc.NewPage().Graphics
            Dim ii = imageInfos(i)
            g.DrawImage(ii.Image, rBig, Nothing, ia)
            ii.PageIdx = i
        Next
        '' 将带有缩略图的页面作为 4x5 网格插入到文档的开头(请参阅SlidePages):
        Const rows = 5
        Const cols = 4
        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
        '' 缩略图也垂直居中:
        ia.AlignVert = ImageAlignVert.Center
        '' 图像标题的文本格式:
        Dim tf = New TextFormat() With {.Font = fnt, .FontSize = sMargin * 0.65F}
        '' 插入点:
        Dim ip = New PointF(margin, margin)
        Dim page = doc.Pages.Insert(0)
        For i = 0 To imageInfos.Count() - 1
            Dim ii = imageInfos(i)
            Dim rect = New RectangleF(ip, New SizeF(sWidth - gapx, sHeight - gapy))
            '' 添加全尺寸图像所在页面的链接(页面索引
            '' 当我们知道目录中有多少页时,将会更新,见下文):
            page.Annotations.Add(New LinkAnnotation(rect, New DestinationFit(ii.PageIdx)))
            '' 绘制缩略图:
            Dim g = page.Graphics
            g.FillRectangle(rect, Color.LightGray)
            g.DrawRectangle(rect, Color.Black, 0.5F)
            rect.Inflate(-sMargin, -sMargin)
            Dim imageRect As RectangleF() = Nothing
            g.DrawImage(ii.Image, rect, Nothing, ia, imageRect)
            g.DrawRectangle(imageRect(0), Color.DarkGray, 1)
            '' 在幻灯片底部边距中打印图像文件名作为标题:
            g.DrawString(ii.Name, 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) Then
                ip.X = margin
                ip.Y += sHeight
                If (ip.Y + sHeight > doc.PageSize.Height) Then
                    page = doc.Pages.Insert(doc.Pages.IndexOf(page) + 1)
                    ip.Y = margin
                End If
            End If
        Next
        '' 我们现在浏览所有目录页面,更新链接目的地中的页面索引
        '' 考虑到文档开头插入的目录页:
        Dim tocPages = doc.Pages.IndexOf(page) + 1
        For i = 0 To tocPages - 1
            For Each ann In doc.Pages(i).Annotations
                If TypeOf ann Is LinkAnnotation AndAlso TypeOf CType(ann, LinkAnnotation).Dest Is DestinationFit Then
                    Dim link = DirectCast(ann, LinkAnnotation)
                    Dim dest = DirectCast(CType(ann, LinkAnnotation).Dest, DestinationFit)
                    link.Dest = New DestinationFit(dest.PageIndex.Value + tocPages)
                End If
            Next
        Next
        ''
        '' 完毕:
        doc.Save(stream)
        imageInfos.ForEach(Sub(ii_) ii_.Image.Dispose())
        Return doc.Pages.Count
    End Function
End Class