''
'' 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.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
'' This sample loads all images found in a directory, then renders each image
'' in the largest possible size on a separate page of the PDF.
'' Finally it inserts a TOC of image thumbnails linked to the large images
'' into the document.
'' See also 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" page margins all around:
Const margin = 36.0F
'' Load all images from the Resources/Images folder:
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()
'' Set up image alignment that would center images horizontally and align to top vertically:
Dim ia = New ImageAlign(ImageAlignHorz.Center, ImageAlignVert.Top, True, True, True, False, False)
'' Image rectangle for full-sized images - whole page:
Dim rBig = New RectangleF(margin, margin, doc.PageSize.Width - margin * 2, doc.PageSize.Height - margin * 2)
'' Render all images full-size, one image per page:
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
'' Insert page(s) with thumbnails into the beginning of the document as a 4x5 grid (see 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
'' Center thumbnails vertically too:
ia.AlignVert = ImageAlignVert.Center
'' 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 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))
'' Add a link to the page where the full-sized image is (the page index
'' will be updated when we know how many pages are in TOC, see below):
page.Annotations.Add(New LinkAnnotation(rect, New DestinationFit(ii.PageIdx)))
'' Draw thumbnail:
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)
'' Print image file name as caption in the bottom slide margin:
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
'' We now go through all TOC pages, updating page indices in links' destinations
'' to account for the TOC pages inserted in the beginning of the document:
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
''
'' Done:
doc.Save(stream)
imageInfos.ForEach(Sub(ii_) ii_.Image.Dispose())
Return doc.Pages.Count
End Function
End Class