ImageArticles.vb
  1. ''
  2. '' This code is part of Document Solutions for PDF demos.
  3. '' Copyright (c) MESCIUS inc. All rights reserved.
  4. ''
  5. Imports System.IO
  6. Imports System.Drawing
  7. Imports System.Linq
  8. Imports System.Collections.Generic
  9. Imports GrapeCity.Documents.Pdf
  10. Imports GrapeCity.Documents.Pdf.Articles
  11. Imports GrapeCity.Documents.Imaging
  12. Imports GrapeCity.Documents.Drawing
  13.  
  14. '' This sample shows how to create article threads in a PDF document.
  15. '' An article thread Is a sequence of related pages Or page areas that can be
  16. '' navigated sequentially (forward Or back) in a supporting PDF viewer.
  17. '' In this sample we load a number of photos from a folder And render them
  18. '' one per page in a random order.
  19. '' Some photos are associated (via known file names) with a specific subject
  20. '' (buildings, art, etc.), And we put all images associated with
  21. '' each subject into a subject-specific article thread (images that are Not
  22. '' associated with any known subject are put in the 'Miscellaneous' thread).
  23. '' In addition we create 3 threads for different aspect ratios (horizontal,
  24. '' vertical And square), And add each image to the appropriate aspect article.
  25. '' See section 'Article threads' in Navigating PDF pages
  26. '' for details on how to navigate article threads in Acrobat
  27. '' (our JavaScript PDF viewer provides a similar UI for this).
  28. Public Class ImageArticles
  29. '' Article names:
  30. Class ArticleNames
  31. Public Shared Landscape = "Subject: landscape"
  32. Public Shared Art = "Subject: art"
  33. Public Shared Flora = "Subject: flora"
  34. Public Shared Buildings = "Subject: buildings"
  35. Public Shared Misc = "Subject: Miscellaneous"
  36. Public Shared AspectHorz = "Aspect: horizontal"
  37. Public Shared AspectVert = "Aspect: vertical"
  38. Public Shared AspectSquare = "Aspect: square"
  39. End Class
  40.  
  41. '' Associate known image file names with appropriate subjects:
  42. Shared _subjects As New Dictionary(Of String, String)() From
  43. {
  44. {"aurora.jpg", ArticleNames.Landscape},
  45. {"chairs.jpg", ArticleNames.Buildings},
  46. {"clouds.jpg", ArticleNames.Landscape},
  47. {"colosseum.jpg", ArticleNames.Art},
  48. {"deadwood.jpg", ArticleNames.Flora},
  49. {"door.jpg", ArticleNames.Buildings},
  50. {"ferns.jpg", ArticleNames.Flora},
  51. {"fiord.jpg", ArticleNames.Landscape},
  52. {"firth.jpg", ArticleNames.Landscape},
  53. {"lady.jpg", ArticleNames.Art},
  54. {"lavender.jpg", ArticleNames.Flora},
  55. {"maple.jpg", ArticleNames.Buildings},
  56. {"minerva.jpg", ArticleNames.Art},
  57. {"newfoundland.jpg", ArticleNames.Landscape},
  58. {"pines.jpg", ArticleNames.Flora},
  59. {"purples.jpg", ArticleNames.Flora},
  60. {"reds.jpg", ArticleNames.Flora},
  61. {"road.jpg", ArticleNames.Landscape},
  62. {"rome.jpg", ArticleNames.Art},
  63. {"roofs.jpg", ArticleNames.Buildings},
  64. {"sea.jpg", ArticleNames.Landscape},
  65. {"skye.jpg", ArticleNames.Landscape},
  66. {"tudor.jpg", ArticleNames.Buildings},
  67. {"windswept.jpg", ArticleNames.Flora}
  68. }
  69. '' Images not in this list are 'misc'.
  70.  
  71. '' Class to hold image info:
  72. Class ImageInfo
  73. Public Name As String
  74. Public Image As IImage
  75. Public Subject As String
  76. Public Aspect As String
  77. End Class
  78.  
  79. Function CreatePDF(ByVal stream As Stream) As Integer
  80. '' Load images and their associated infos:
  81. Dim imageInfos = New List(Of ImageInfo)
  82. For Each fname In Directory.GetFiles(Path.Combine("Resources", "Images"), "*", SearchOption.AllDirectories)
  83. Dim image = Util.ImageFromFile(fname)
  84. Dim aspect As String
  85. If image.Width > image.Height Then
  86. aspect = ArticleNames.AspectHorz
  87. ElseIf image.Width < image.Height Then
  88. aspect = ArticleNames.AspectVert
  89. Else
  90. aspect = ArticleNames.AspectSquare
  91. End If
  92. Dim name = Path.GetFileName(fname)
  93. Dim subject As String = Nothing
  94. _subjects.TryGetValue(name, subject)
  95. If String.IsNullOrEmpty(subject) Then
  96. subject = ArticleNames.Misc
  97. End If
  98. imageInfos.Add(New ImageInfo() With {
  99. .Name = name,
  100. .Image = image,
  101. .Subject = subject,
  102. .Aspect = aspect
  103. })
  104. Next
  105. '' Randomize the order of images in the PDF:
  106. imageInfos.Shuffle()
  107.  
  108. '' Keys are article thread names (from ArticleNames),
  109. '' values are ArticleThread objects to be added to the PDF:
  110. Dim articles = New Dictionary(Of String, ArticleThread)()
  111. For Each subject In _subjects.Values.Distinct()
  112. articles.Add(subject,
  113. New ArticleThread() With {
  114. .Info = New DocumentInfo() With {.Title = subject}
  115. })
  116. Next
  117. articles.Add(ArticleNames.Misc,
  118. New ArticleThread() With {.Info = New DocumentInfo() With {.Title = ArticleNames.Misc}})
  119. Dim horizontals = New ArticleThread() With {.Info = New DocumentInfo() With {.Title = ArticleNames.AspectHorz}}
  120. Dim verticals = New ArticleThread() With {.Info = New DocumentInfo() With {.Title = ArticleNames.AspectVert}}
  121. Dim squares = New ArticleThread() With {.Info = New DocumentInfo() With {.Title = ArticleNames.AspectSquare}}
  122.  
  123. '' Create the document:
  124. Dim doc = New GcPdfDocument()
  125.  
  126. '' Add images (one per page) to the PDF and article threads:
  127. Dim ia = New ImageAlign(ImageAlignHorz.Center, ImageAlignVert.Top, True, True, True, False, False)
  128. For i = 0 To imageInfos.Count - 1
  129. Dim page = doc.NewPage()
  130. Dim ii = imageInfos(i)
  131. Dim rc = New RectangleF(72, 72, doc.PageSize.Width - 144, doc.PageSize.Height - 144)
  132. '' Note that we get the actual image bounds to precisely specify the page area in the thread:
  133. Dim imageBounds As RectangleF() = Nothing
  134. page.Graphics.DrawImage(ii.Image, rc, Nothing, ia, imageBounds)
  135. Dim bounds = imageBounds(0)
  136. '' Add the image to proper subject and aspect threads:
  137. articles(ii.Subject).Beads.Add(New ArticleBead() With {.Page = page, .Bounds = bounds})
  138. If (ii.Aspect = ArticleNames.AspectHorz) Then
  139. horizontals.Beads.Add(New ArticleBead() With {.Page = page, .Bounds = bounds})
  140. ElseIf (ii.Aspect = ArticleNames.AspectVert) Then
  141. verticals.Beads.Add(New ArticleBead() With {.Page = page, .Bounds = bounds})
  142. Else
  143. squares.Beads.Add(New ArticleBead() With {.Page = page, .Bounds = bounds})
  144. End If
  145. Next
  146. '' Add subject and aspect article threads to the PDF:
  147. For Each article In articles.Select(Function(a_) a_.Value)
  148. doc.ArticleThreads.Add(article)
  149. Next
  150. doc.ArticleThreads.Add(horizontals)
  151. doc.ArticleThreads.Add(verticals)
  152. doc.ArticleThreads.Add(squares)
  153.  
  154. '' Done
  155. doc.Save(stream)
  156. Return doc.Pages.Count
  157. End Function
  158. End Class
  159.