ImageLinks.vb
''
'' このコードは、DioDocs for PDF のサンプルの一部として提供されています。
'' © 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
'' このサンプルは、ディレクトリ内にあるすべての画像を読み込み、
'' 各画像を 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)
'' 各ページに1つずつフルサイズの画像を描画します。
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
''
'' PDF ドキュメントを保存します。
doc.Save(stream)
imageInfos.ForEach(Sub(ii_) ii_.Image.Dispose())
Return doc.Pages.Count
End Function
End Class