''
'' This code is part of Document Solutions for PDF demos.
'' Copyright (c) MESCIUS inc. All rights reserved.
''
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
'' This sample shows how to create article threads in a PDF document.
'' An article thread Is a sequence of related pages Or page areas that can be
'' navigated sequentially (forward Or back) in a supporting PDF viewer.
'' In this sample we load a number of photos from a folder And render them
'' one per page in a random order.
'' Some photos are associated (via known file names) with a specific subject
'' (buildings, art, etc.), And we put all images associated with
'' each subject into a subject-specific article thread (images that are Not
'' associated with any known subject are put in the 'Miscellaneous' thread).
'' In addition we create 3 threads for different aspect ratios (horizontal,
'' vertical And square), And add each image to the appropriate aspect article.
'' See section 'Article threads' in Navigating PDF pages
'' for details on how to navigate article threads in Acrobat
'' (our JavaScript PDF viewer provides a similar UI for this).
Public Class ImageArticles
'' Article names:
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
'' Associate known image file names with appropriate subjects:
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}
}
'' Images not in this list are 'misc'.
'' Class to hold image info:
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
'' Load images and their associated infos:
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
'' Randomize the order of images in the PDF:
imageInfos.Shuffle()
'' Keys are article thread names (from ArticleNames),
'' values are ArticleThread objects to be added to the PDF:
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}}
'' Create the document:
Dim doc = New GcPdfDocument()
'' Add images (one per page) to the PDF and article threads:
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)
'' Note that we get the actual image bounds to precisely specify the page area in the thread:
Dim imageBounds As RectangleF() = Nothing
page.Graphics.DrawImage(ii.Image, rc, Nothing, ia, imageBounds)
Dim bounds = imageBounds(0)
'' Add the image to proper subject and aspect threads:
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
'' Add subject and aspect article threads to the 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)
'' Done
doc.Save(stream)
Return doc.Pages.Count
End Function
End Class