Ik ben inmiddels een tijd bezig met het automatich laten genereren van thumbnails voor een grote collectie aan pdf-bestanden. Hiervoor heb ik in visual studio 2k5 een tooltje gebouwd dat recursive vanuit een startdirectory alle pdf bestanden afloopt, en hier een thumbnail voor maakt.
Nu werkt het programma prima, en genereert het naar hartelust thumbnails, maar geeft het consequent na 256 files de brui eraan, met een filenotfound exception (zie hieronder voor de exacte foutmelding). Aangezien 256 natuurlijk in de digitale wereld een zeer kenmerkend getal is, vermoed ik dat het ergens tegen een grens aanloopt. Ik zie inmiddels echter door de bomen het bos niet meer, en google helpt mij ook niet meer verder.
Elke hulp/hint in de goede richting is welkom.
De foutmelding die hij geeft:
System.IO.FileNotFoundException: Unable to find the specified file.
at PDFThumbnail.PDFThumbnail.DirSearch(String sDir)
De code:
Nu werkt het programma prima, en genereert het naar hartelust thumbnails, maar geeft het consequent na 256 files de brui eraan, met een filenotfound exception (zie hieronder voor de exacte foutmelding). Aangezien 256 natuurlijk in de digitale wereld een zeer kenmerkend getal is, vermoed ik dat het ergens tegen een grens aanloopt. Ik zie inmiddels echter door de bomen het bos niet meer, en google helpt mij ook niet meer verder.
Elke hulp/hint in de goede richting is welkom.
De foutmelding die hij geeft:
System.IO.FileNotFoundException: Unable to find the specified file.
at PDFThumbnail.PDFThumbnail.DirSearch(String sDir)
De code:
Visual Basic .NET:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
| Imports System.IO Imports System.Runtime.InteropServices Imports System.Drawing.Graphics Imports System.Configuration Module PDFThumbnail Sub Main() ' Declaring startdir from commandline if passed on, else using ' the settings from the configuration file (no trailing slash) Dim appSettings As AppSettingsReader = New AppSettingsReader Dim sDir As String If Command() = "" Then With appSettings sDir = .GetValue("startDir", GetType(String)) End With Else sDir = Command() End If ' Passing startdir on to the recursive sub dirsearch DirSearch(sDir) End Sub Sub DirSearch(ByVal sDir As String) ' Acrobat objects Dim pdfDoc As Acrobat.CAcroPDDoc Dim pdfPage As Acrobat.CAcroPDPage Dim pdfRect As Acrobat.CAcroRect Dim pdfRectTemp As Object ' Objects for dirs and files in recursive process Dim d As String Dim f As String ' Requesting variables from appsettings file Dim appSettings As AppSettingsReader = New AppSettingsReader Dim jpgOutputPath As String Dim thumbnailWidth As Integer Dim thumbnailHeight As Integer With appSettings jpgOutputPath = .GetValue("jpgOutputPath", GetType(String)) End With ' Setting location for overlay images, the actual overlay can be enabled later on Dim templatePortraitFile As String = Application.StartupPath & "\thumb-portrait.gif" Dim templateLandscapeFile As String = Application.StartupPath & "\thumb-landscape.gif" Try ' Get list of files to process from the startdir for the first run ' Second and further runs use dir from its own recursive process For Each d In Directory.GetDirectories(sDir) For Each f In Directory.GetFiles(d, "*.pdf") ' Replacing inputdir with outputdir and pdf extension with jpg ' Pattern match for pdf is case sensitive, currently only lowercase ' extensions are incluided properly. Dim inputFile As String = f Dim outputFile As String = f.ToString.Replace(d, jpgOutputPath).Replace(".pdf", ".jpg") ' Dim pageCount As Integer Dim ret As Integer ' Skipping if thumbnail already exists in output path Dim fi As New FileInfo(outputFile) If Not fi.Exists() Then ' Create the document (Can only create the AcroExch.PDDoc object using late-binding) pdfDoc = CreateObject("AcroExch.PDDoc") ' Open the document ret = pdfDoc.Open(inputFile) If ret = False Then Throw New FileNotFoundException End If ' Get the number of pages ' pageCount = pdfDoc.GetNumPages() ' Get the first page pdfPage = pdfDoc.AcquirePage(0) ' Get the size of the page ' This is really strange bug/documentation problem ' The PDFRect you get back from GetSize has properties ' x and y, but the PDFRect you have to supply CopyToClipboard ' has left, right, top, bottom pdfRectTemp = pdfPage.GetSize ' Create PDFRect to hold dimensions of the page pdfRect = CreateObject("AcroExch.Rect") pdfRect.Left = 0 pdfRect.right = pdfRectTemp.x pdfRect.Top = 0 pdfRect.bottom = pdfRectTemp.y ' Render to clipboard, scaled by 100 percent (ie. original size) ' Even though we want a smaller image, better for us to scale in .NET ' than Acrobat as it would greek out small text. Call pdfPage.CopyToClipboard(pdfRect, 0, 0, 100) Dim clipboardData As IDataObject = Clipboard.GetDataObject() If (clipboardData.GetDataPresent(DataFormats.Bitmap)) Then Dim pdfBitmap As Bitmap = clipboardData.GetData(DataFormats.Bitmap) Dim templateFile As String ' Switch between portrait and landscape If (pdfRectTemp.x < pdfRectTemp.y) Then templateFile = templatePortraitFile With appSettings thumbnailWidth = .GetValue("thumbnailWidthPortrait", GetType(Integer)) thumbnailHeight = .GetValue("thumbnailHeightPortrait", GetType(Integer)) End With Else templateFile = templateLandscapeFile With appSettings thumbnailWidth = .GetValue("thumbnailWidthLandscape", GetType(Integer)) thumbnailHeight = .GetValue("thumbnailHeightLandscape", GetType(Integer)) End With End If ' Load the template graphic Dim templateBitmap As Bitmap = New Bitmap(templateFile) Dim templateImage As Image = Image.FromFile(templateFile) ' Render to small image using the bitmap class Dim pdfImage As Image = pdfBitmap.GetThumbnailImage(thumbnailWidth, _ thumbnailHeight, _ Nothing, Nothing) ' Create new blank bitmap Dim thumbnailBitmap As Bitmap = New Bitmap(thumbnailWidth, _ thumbnailHeight, _ Imaging.PixelFormat.Format32bppArgb) ' To overlayout the template with the image, we need to set the transparency templateBitmap.MakeTransparent() Dim thumbnailGraphics As Graphics = Graphics.FromImage(thumbnailBitmap) ' Draw rendered pdf image to new blank bitmap thumbnailGraphics.DrawImage(pdfImage, 0, 0, thumbnailWidth, thumbnailHeight) ' Draw template outline over the bitmap (enable to use overlay) thumbnailGraphics.DrawImage(templateImage, 0, 0) ' Save as .jpg file. Using jpg here since png would make the files ' several times bigger for the currently default thumb size. thumbnailBitmap.Save(outputFile, Imaging.ImageFormat.Jpeg) ' Writing to console if thumbnail is created properly Console.WriteLine("Generated thumbnail... {0}", outputFile, thumbnailWidth, thumbnailHeight) ' thumbnailWidth = Nothing ' thumbnailHeight = Nothing thumbnailGraphics.Dispose() pdfDoc.Close() Marshal.ReleaseComObject(pdfPage) Marshal.ReleaseComObject(pdfRect) Marshal.ReleaseComObject(pdfDoc) End If End If Next ' After all files in current dir have been processed, passing on ' Next dir to process. DirSearch(d) Next Catch ex As Exception Console.WriteLine(ex) End Try End Sub End Module |