ImageArticles.vb
'' 完毕:
Imports System.IO
Imports System.Drawing
Imports System.Linq
Imports System.Collections.Generic
Imports GrapeCity.Documents.Pdf
Imports GrapeCity.Documents.Pdf.Articles
Imports GrapeCity.Documents.Imaging
Imports GrapeCity.Documents.Drawing

'' 此示例演示如何在 PDF 文档中创建文章线索。
'' 文章线索是一系列相关页面或页面区域,可以
'' 在支持的 PDF 查看器中按顺序导航(向前或向后)。
'' 在此示例中,我们从文件夹加载许多照片并渲染它们
'' 每页一个,顺序随机。
'' 有些照片(通过已知的文件名)与特定主题相关联
'' (建筑物、艺术等),我们将所有与相关的图像
'' 每个主题进入特定主题的文章线程(不是图像
'' 与任何已知主题相关的内容都放在“杂项”线程中)。
'' 此外,我们还为不同的纵横比创建了 3 个线程(水平、
'' 垂直和方形),并将每个图像添加到相应的方面文章中。
'' 请参阅 导览 PDF 页面
'' 有关如何在 Acrobat 中导航文章线索的详细信息
'' (我们的 JavaScript PDF 查看器为此提供了类似的 UI)。
Public Class ImageArticles
    '' 文章名称:
    Class ArticleNames
        Public Shared Landscape = "Subject: landscape"
        Public Shared Art = "Subject: art"
        Public Shared Flora = "Subject: flora"
        Public Shared Buildings = "Subject: buildings"
        Public Shared Misc = "Subject: Miscellaneous"
        Public Shared AspectHorz = "Aspect: horizontal"
        Public Shared AspectVert = "Aspect: vertical"
        Public Shared AspectSquare = "Aspect: square"
    End Class

    '' 将已知图像文件名与适当的主题相关联:
    Shared _subjects As New Dictionary(Of String, String)() From
        {
            {"aurora.jpg", ArticleNames.Landscape},
            {"chairs.jpg", ArticleNames.Buildings},
            {"clouds.jpg", ArticleNames.Landscape},
            {"colosseum.jpg", ArticleNames.Art},
            {"deadwood.jpg", ArticleNames.Flora},
            {"door.jpg", ArticleNames.Buildings},
            {"ferns.jpg", ArticleNames.Flora},
            {"fiord.jpg", ArticleNames.Landscape},
            {"firth.jpg", ArticleNames.Landscape},
            {"lady.jpg", ArticleNames.Art},
            {"lavender.jpg", ArticleNames.Flora},
            {"maple.jpg", ArticleNames.Buildings},
            {"minerva.jpg", ArticleNames.Art},
            {"newfoundland.jpg", ArticleNames.Landscape},
            {"pines.jpg", ArticleNames.Flora},
            {"purples.jpg", ArticleNames.Flora},
            {"reds.jpg", ArticleNames.Flora},
            {"road.jpg", ArticleNames.Landscape},
            {"rome.jpg", ArticleNames.Art},
            {"roofs.jpg", ArticleNames.Buildings},
            {"sea.jpg", ArticleNames.Landscape},
            {"skye.jpg", ArticleNames.Landscape},
            {"tudor.jpg", ArticleNames.Buildings},
            {"windswept.jpg", ArticleNames.Flora}
        }
    '' 不在此列表中的图像为“杂项”。

    '' 保存图像信息的类:
    Class ImageInfo
        Public Name As String
        Public Image As IImage
        Public Subject As String
        Public Aspect As String
    End Class

    Function CreatePDF(ByVal stream As Stream) As Integer
        '' 加载图像及其相关信息:
        Dim imageInfos = New List(Of ImageInfo)
        For Each fname In Directory.GetFiles(Path.Combine("Resources", "Images"), "*", SearchOption.AllDirectories)
            Dim image = Util.ImageFromFile(fname)
            Dim aspect As String
            If image.Width > image.Height Then
                aspect = ArticleNames.AspectHorz
            ElseIf image.Width < image.Height Then
                aspect = ArticleNames.AspectVert
            Else
                aspect = ArticleNames.AspectSquare
            End If
            Dim name = Path.GetFileName(fname)
            Dim subject As String = Nothing
            _subjects.TryGetValue(name, subject)
            If String.IsNullOrEmpty(subject) Then
                subject = ArticleNames.Misc
            End If
            imageInfos.Add(New ImageInfo() With {
                .Name = name,
                .Image = image,
                .Subject = subject,
                .Aspect = aspect
                })
        Next
        '' 随机化 PDF 中图像的顺序:
        imageInfos.Shuffle()

        '' 键是文章主题名称(来自 ArticleNames),
        '' 值是要添加到 PDF 的 ArticleThread 对象:
        Dim articles = New Dictionary(Of String, ArticleThread)()
        For Each subject In _subjects.Values.Distinct()
            articles.Add(subject,
                         New ArticleThread() With {
                            .Info = New DocumentInfo() With {.Title = subject}
                         })
        Next
        articles.Add(ArticleNames.Misc,
                     New ArticleThread() With {.Info = New DocumentInfo() With {.Title = ArticleNames.Misc}})
        Dim horizontals = New ArticleThread() With {.Info = New DocumentInfo() With {.Title = ArticleNames.AspectHorz}}
        Dim verticals = New ArticleThread() With {.Info = New DocumentInfo() With {.Title = ArticleNames.AspectVert}}
        Dim squares = New ArticleThread() With {.Info = New DocumentInfo() With {.Title = ArticleNames.AspectSquare}}

        '' 创建文档:
        Dim doc = New GcPdfDocument()

        '' 将图像(每页一张)添加到 PDF 和文章线程:
        Dim ia = New ImageAlign(ImageAlignHorz.Center, ImageAlignVert.Top, True, True, True, False, False)
        For i = 0 To imageInfos.Count - 1
            Dim page = doc.NewPage()
            Dim ii = imageInfos(i)
            Dim rc = New RectangleF(72, 72, doc.PageSize.Width - 144, doc.PageSize.Height - 144)
            '' 请注意,我们获取实际图像边界以精确指定线程中的页面区域:
            Dim imageBounds As RectangleF() = Nothing
            page.Graphics.DrawImage(ii.Image, rc, Nothing, ia, imageBounds)
            Dim bounds = imageBounds(0)
            '' 将图像添加到适当的主题和方面线程:
            articles(ii.Subject).Beads.Add(New ArticleBead() With {.Page = page, .Bounds = bounds})
            If (ii.Aspect = ArticleNames.AspectHorz) Then
                horizontals.Beads.Add(New ArticleBead() With {.Page = page, .Bounds = bounds})
            ElseIf (ii.Aspect = ArticleNames.AspectVert) Then
                verticals.Beads.Add(New ArticleBead() With {.Page = page, .Bounds = bounds})
            Else
                squares.Beads.Add(New ArticleBead() With {.Page = page, .Bounds = bounds})
            End If
        Next
        '' 将主题和方面文章线程添加到 PDF:
        For Each article In articles.Select(Function(a_) a_.Value)
            doc.ArticleThreads.Add(article)
        Next
        doc.ArticleThreads.Add(horizontals)
        doc.ArticleThreads.Add(verticals)
        doc.ArticleThreads.Add(squares)

        '' 完毕:
        doc.Save(stream)
        Return doc.Pages.Count
    End Function
End Class