Texte einer PDF bearbeiten

  • VB.NET

Es gibt 15 Antworten in diesem Thema. Der letzte Beitrag () ist von -Franky-.

    Texte einer PDF bearbeiten

    Hallo,
    Ich muss PDF bearbeiten und dabei bestimmte Texte (diese sind immer gleich) ändern.
    Ich habe mich schonmal versucht mit itextsharp.

    VB.NET-Quellcode

    1. Dim Pfad As String = "S:\Austausch\Fiedler\VB.net\Datenblatt\Test - Kopie.pdf"
    2. Using reader As PdfReader = New PdfReader(Pfad)
    3. Dim Text As StringBuilder = New StringBuilder()
    4. For i = 1 To reader.NumberOfPages
    5. Text.Append(PdfTextExtractor.GetTextFromPage(reader, i))
    6. MsgBox(Text.ToString)
    7. Text.Replace("BL?", "999")
    8. MsgBox(Text.ToString)
    9. Text.ToString()
    10. Next
    11. End Using


    In der ersten Msgbox findet man den gewünschten Wert "BL?" und dieser ist dann in der 2. Msgbox auch auf "999" geändert.
    Aber die PDF bleibt unverändert, wie bekomm ich das jetzt auf die PDF?
    @fiedel93felix Wie ganz genau sieht denn die Deklaration von .Replace() aus :?:
    learn.microsoft.com/de-de/dotn…ring.replace?view=net-7.0
    Wie funktioniert .Replace() :?:
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    @fiedel93felix Naja, mit Replace wird nur der gefundenen Text (GetTextFromPage) ersetzt. Wo bzw. wann schreibst Du den geänderten Text in die PDF zurück? Mal so als Anregung: medium.com/@sampathsl/changing…ext-in-a-pdf-d82a16219c5c Bei der alten itextsharp Version musste man noch Änderungen in ein neues PDF speichern. Ob das mit einer akltuellen Version auch noch so ist, kann ich Dir nicht sagen. Denke da lässt sich sicher einiges mehr über eine Suchmaschine Deines Vertrauens finden.
    Mfg -Franky-
    Sorry, das ist ja ein StringBuilder, das ist mir total durch die Lappen gegangen.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Hallo, ich habe einen Code in C# gefunden den ich umgeschrieben haben und testen wollte.
    Allerdings hab ich bei einer Zeile Probleme.
    Wie übersetze ich:

    C#-Quellcode

    1. List<iTextSharp.text.Rectangle> MatchesFound = strategy.GetTextLocations(pSearch, SC);


    Siehe anbei mein Versuch mit Fehlermeldung.
    Bilder
    • Fehlermeldung.PNG

      58,23 kB, 1.181×346, 70 mal angesehen
    das Of fehlt, also …As List(Of iTextSharp.text.Recangle)

    btw: iTextSharp ist obsolet. Es sollte der Nachfolger iText7 verwendet/über Nuget bezogen werden.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    Der Code läuft jetzt aber das Ergebniss nicht nicht im Ansatz ausreichend.

    Anbei der Code und das Beispiel in original und bearbeitet.
    Hat jemand einen anderen Code der besser funktioniert?
    Spoiler anzeigen

    Quellcode

    1. Imports iTextSharp.text
    2. Imports iTextSharp.text.pdf
    3. Imports iTextSharp.text.pdf.parser
    4. Imports System.Diagnostics.Eventing
    5. Imports System.IO
    6. Imports System.Text
    7. Module Module1
    8. Sub Main()
    9. Dim stamper As iTextSharp.text.pdf.PdfStamper = Nothing
    10. Dim pSearch(99) As String
    11. Dim replacingText(99) As String
    12. For i = 1 To 99
    13. pSearch(99) = ""
    14. replacingText(99) = ""
    15. Next
    16. pSearch(1) = "BL?"
    17. replacingText(1) = "120"
    18. pSearch(2) = "FD1?"
    19. replacingText(2) = "Ø180"
    20. pSearch(3) = "FK1?"
    21. replacingText(3) = "Ø150/4xØ18"
    22. pSearch(4) = "Projekt?"
    23. replacingText(4) = "TestProjekt"
    24. pSearch(5) = "ANr?"
    25. replacingText(5) = ""
    26. pSearch(6) = "Werkstoff"
    27. replacingText(6) = "1.4541"
    28. pSearch(7) = "Stückzahl?"
    29. replacingText(7) = "10"
    30. pSearch(8) = "Kompensator?"
    31. replacingText(8) = "Axialkompensator"
    32. Dim SourceFile As String = "S:\Austausch\Fiedler\VB.net\Datenblatt\Test - Kopie.pdf"
    33. If Not System.IO.File.Exists(SourceFile) Then MsgBox("PDF nicht gefunden!") : Exit Sub
    34. Dim DestinationFile As String = "S:\Austausch\Fiedler\VB.net\Datenblatt\TestNeu.pdf"
    35. Dim pReader As PdfReader = New PdfReader(sourceFile)
    36. Dim SC As StringComparison = StringComparison.CurrentCultureIgnoreCase
    37. stamper = New iTextSharp.text.pdf.PdfStamper(pReader, New System.IO.FileStream(DestinationFile, System.IO.FileMode.Create))
    38. Try
    39. Dim cb As iTextSharp.text.pdf.PdfContentByte = Nothing
    40. Dim cb2 As iTextSharp.text.pdf.PdfContentByte = Nothing
    41. Dim writer As iTextSharp.text.pdf.PdfWriter = Nothing
    42. Dim bf As iTextSharp.text.pdf.BaseFont = Nothing
    43. For page As Integer = 1 To pReader.NumberOfPages
    44. Dim strategy As myLocationTextExtractionStrategy = New myLocationTextExtractionStrategy()
    45. cb = stamper.GetOverContent(page)
    46. cb2 = stamper.GetOverContent(page)
    47. strategy.UndercontentCharacterSpacing = CInt(cb.CharacterSpacing)
    48. strategy.UndercontentHorizontalScaling = CInt(cb.HorizontalScaling)
    49. Dim currentText As String = PdfTextExtractor.GetTextFromPage(pReader, page, strategy)
    50. 'Dim MatchesFound As List(Of iTextSharp.text.Rectangle) = strategy.GetTextLocations(pSearch, SC)
    51. Dim MatchesFound As List(Of iTextSharp.text.Rectangle)
    52. For i = 1 To 99
    53. If pSearch(i) = "" Then Exit For
    54. MatchesFound = strategy.GetTextLocations(pSearch(i), SC)
    55. cb.SetColorFill(BaseColor.WHITE)
    56. For Each rect As iTextSharp.text.Rectangle In MatchesFound
    57. cb.Rectangle(rect.Left, rect.Bottom, 60, rect.Height)
    58. cb.Fill()
    59. cb2.SetColorFill(BaseColor.BLACK)
    60. bf = BaseFont.CreateFont(BaseFont.HELVETICA_BOLD, BaseFont.CP1252, BaseFont.NOT_EMBEDDED)
    61. cb2.SetFontAndSize(bf, 9)
    62. cb2.BeginText()
    63. cb2.ShowTextAligned(0, replacingText(i), rect.Left, rect.Bottom, 0)
    64. cb2.EndText()
    65. cb2.Fill()
    66. Next
    67. Next
    68. Next
    69. Catch ex As Exception
    70. End Try
    71. stamper.Close()
    72. pReader.Close()
    73. MsgBox("fertig!")
    74. End Sub
    75. Public Class myLocationTextExtractionStrategy
    76. Implements ITextExtractionStrategy
    77. '* set to true for debugging
    78. Private _UndercontentCharacterSpacing = 0
    79. Private _UndercontentHorizontalScaling = 0
    80. Private ThisPdfDocFonts As SortedList(Of String, DocumentFont)
    81. Public Shared DUMP_STATE As Boolean = False
    82. '* a summary of all found text
    83. Private locationalResult As New List(Of TextChunk)()
    84. '*
    85. ' * Creates a new text extraction renderer.
    86. '
    87. Public Sub New()
    88. ThisPdfDocFonts = New SortedList(Of String, DocumentFont)
    89. End Sub
    90. '*
    91. ' * @see com.itextpdf.text.pdf.parser.RenderListener#beginTextBlock()
    92. '
    93. Public Overridable Sub BeginTextBlock() Implements ITextExtractionStrategy.BeginTextBlock
    94. End Sub
    95. '*
    96. ' * @see com.itextpdf.text.pdf.parser.RenderListener#endTextBlock()
    97. '
    98. Public Overridable Sub EndTextBlock() Implements ITextExtractionStrategy.EndTextBlock
    99. End Sub
    100. '*
    101. ' * @param str
    102. ' * @return true if the string starts with a space character, false if the string is empty or starts with a non-space character
    103. '
    104. Private Function StartsWithSpace(ByVal str As [String]) As Boolean
    105. If str.Length = 0 Then
    106. Return False
    107. End If
    108. Return str(0) = " "c
    109. End Function
    110. '*
    111. ' * @param str
    112. ' * @return true if the string ends with a space character, false if the string is empty or ends with a non-space character
    113. '
    114. Private Function EndsWithSpace(ByVal str As [String]) As Boolean
    115. If str.Length = 0 Then
    116. Return False
    117. End If
    118. Return str(str.Length - 1) = " "c
    119. End Function
    120. Public Property UndercontentCharacterSpacing
    121. Get
    122. Return _UndercontentCharacterSpacing
    123. End Get
    124. Set(ByVal value)
    125. _UndercontentCharacterSpacing = value
    126. End Set
    127. End Property
    128. Public Property UndercontentHorizontalScaling
    129. Get
    130. Return _UndercontentHorizontalScaling
    131. End Get
    132. Set(ByVal value)
    133. _UndercontentHorizontalScaling = value
    134. End Set
    135. End Property
    136. Public Overridable Function GetResultantText() As [String] Implements ITextExtractionStrategy.GetResultantText
    137. If DUMP_STATE Then
    138. DumpState()
    139. End If
    140. locationalResult.Sort()
    141. Dim sb As New StringBuilder()
    142. Dim lastChunk As TextChunk = Nothing
    143. For Each chunk As TextChunk In locationalResult
    144. If lastChunk Is Nothing Then
    145. sb.Append(chunk.text)
    146. Else
    147. If chunk.SameLine(lastChunk) Then
    148. Dim dist As Single = chunk.DistanceFromEndOf(lastChunk)
    149. If dist < -chunk.charSpaceWidth Then
    150. sb.Append(" "c)
    151. ' we only insert a blank space if the trailing character of the previous string wasn't a space, and the leading character of the current string isn't a space
    152. ElseIf dist > chunk.charSpaceWidth / 2.0F AndAlso Not StartsWithSpace(chunk.text) AndAlso Not EndsWithSpace(lastChunk.text) Then
    153. sb.Append(" "c)
    154. End If
    155. sb.Append(chunk.text)
    156. Else
    157. sb.Append(ControlChars.Lf)
    158. sb.Append(chunk.text)
    159. End If
    160. End If
    161. lastChunk = chunk
    162. Next
    163. Return sb.ToString()
    164. End Function
    165. Public Function GetTextLocations(ByVal pSearchString As String, ByVal pStrComp As System.StringComparison) As List(Of iTextSharp.text.Rectangle)
    166. Dim FoundMatches As New List(Of iTextSharp.text.Rectangle)
    167. Dim sb As New StringBuilder()
    168. Dim ThisLineChunks As List(Of TextChunk) = New List(Of TextChunk)
    169. Dim bStart As Boolean, bEnd As Boolean
    170. Dim FirstChunk As TextChunk = Nothing, LastChunk As TextChunk = Nothing
    171. Dim sTextInUsedChunks As String = vbNullString
    172. For Each chunk As TextChunk In locationalResult
    173. If ThisLineChunks.Count > 0 AndAlso Not chunk.SameLine(ThisLineChunks.Last) Then
    174. If sb.ToString.IndexOf(pSearchString, pStrComp) > -1 Then
    175. Dim sLine As String = sb.ToString
    176. 'Check how many times the Search String is present in this line:
    177. Dim iCount As Integer = 0
    178. Dim lPos As Integer
    179. lPos = sLine.IndexOf(pSearchString, 0, pStrComp)
    180. Do While lPos > -1
    181. iCount += 1
    182. If lPos + pSearchString.Length > sLine.Length Then Exit Do Else lPos = lPos + pSearchString.Length
    183. lPos = sLine.IndexOf(pSearchString, lPos, pStrComp)
    184. Loop
    185. 'Process each match found in this Text line:
    186. Dim curPos As Integer = 0
    187. For i As Integer = 1 To iCount
    188. Dim sCurrentText As String, iFromChar As Integer, iToChar As Integer
    189. iFromChar = sLine.IndexOf(pSearchString, curPos, pStrComp)
    190. curPos = iFromChar
    191. iToChar = iFromChar + pSearchString.Length - 1
    192. sCurrentText = vbNullString
    193. sTextInUsedChunks = vbNullString
    194. FirstChunk = Nothing
    195. LastChunk = Nothing
    196. 'Get first and last Chunks corresponding to this match found, from all Chunks in this line
    197. For Each chk As TextChunk In ThisLineChunks
    198. sCurrentText = sCurrentText & chk.text
    199. 'Check if we entered the part where we had found a matching String then get this Chunk (First Chunk)
    200. If Not bStart AndAlso sCurrentText.Length - 1 >= iFromChar Then
    201. FirstChunk = chk
    202. bStart = True
    203. End If
    204. 'Keep getting Text from Chunks while we are in the part where the matching String had been found
    205. If bStart And Not bEnd Then
    206. sTextInUsedChunks = sTextInUsedChunks & chk.text
    207. End If
    208. 'If we get out the matching String part then get this Chunk (last Chunk)
    209. If Not bEnd AndAlso sCurrentText.Length - 1 >= iToChar Then
    210. LastChunk = chk
    211. bEnd = True
    212. End If
    213. 'If we already have first and last Chunks enclosing the Text where our String pSearchString has been found
    214. 'then it's time to get the rectangle, GetRectangleFromText Function below this Function, there we extract the pSearchString locations
    215. If bStart And bEnd Then
    216. FoundMatches.Add(GetRectangleFromText(FirstChunk, LastChunk, pSearchString, sTextInUsedChunks, iFromChar, iToChar, pStrComp))
    217. curPos = curPos + pSearchString.Length
    218. bStart = False : bEnd = False
    219. Exit For
    220. End If
    221. Next
    222. Next
    223. End If
    224. sb.Clear()
    225. ThisLineChunks.Clear()
    226. End If
    227. ThisLineChunks.Add(chunk)
    228. sb.Append(chunk.text)
    229. Next
    230. Return FoundMatches
    231. End Function
    232. Private Function GetRectangleFromText(ByVal FirstChunk As TextChunk, ByVal LastChunk As TextChunk, ByVal pSearchString As String,
    233. ByVal sTextinChunks As String, ByVal iFromChar As Integer, ByVal iToChar As Integer, ByVal pStrComp As System.StringComparison) As iTextSharp.text.Rectangle
    234. 'There are cases where Chunk contains extra text at begining and end, we don't want this text locations, we need to extract the pSearchString location inside
    235. 'for these cases we need to crop this String (left and Right), and measure this excedent at left and right, at this point we don't have any direct way to make a
    236. 'Transformation from text space points to User Space units, the matrix for making this transformation is not accesible from here, so for these special cases when
    237. 'the String needs to be cropped (Left/Right) We'll interpolate between the width from Text in Chunk (we have this value in User Space units), then i'll measure Text corresponding
    238. 'to the same String but in Text Space units, finally from the relation betweeenthese 2 values I get the TransformationValue I need to use for all cases
    239. 'Text Width in User Space Units
    240. Dim LineRealWidth As Single = LastChunk.PosRight - FirstChunk.PosLeft
    241. 'Text Width in Text Units
    242. Dim LineTextWidth As Single = GetStringWidth(sTextinChunks, LastChunk.curFontSize,
    243. LastChunk.charSpaceWidth,
    244. ThisPdfDocFonts.Values.ElementAt(LastChunk.FontIndex))
    245. 'TransformationValue value for Interpolation
    246. Dim TransformationValue As Single = LineRealWidth / LineTextWidth
    247. 'In the worst case, we'll need to crop left and right:
    248. Dim iStart As Integer = sTextinChunks.IndexOf(pSearchString, pStrComp)
    249. Dim iEnd As Integer = iStart + pSearchString.Length - 1
    250. Dim sLeft As String
    251. If iStart = 0 Then sLeft = vbNullString Else sLeft = sTextinChunks.Substring(0, iStart)
    252. Dim sRight As String
    253. If iEnd = sTextinChunks.Length - 1 Then sRight = vbNullString Else sRight = sTextinChunks.Substring(iEnd + 1, sTextinChunks.Length - iEnd - 1)
    254. 'Measure cropped Text at left:
    255. Dim LeftWidth As Single = 0
    256. If iStart > 0 Then
    257. LeftWidth = GetStringWidth(sLeft, LastChunk.curFontSize,
    258. LastChunk.charSpaceWidth,
    259. ThisPdfDocFonts.Values.ElementAt(LastChunk.FontIndex))
    260. LeftWidth = LeftWidth * TransformationValue
    261. End If
    262. 'Measure cropped Text at right:
    263. Dim RightWidth As Single = 0
    264. If iEnd < sTextinChunks.Length - 1 Then
    265. RightWidth = GetStringWidth(sRight, LastChunk.curFontSize,
    266. LastChunk.charSpaceWidth,
    267. ThisPdfDocFonts.Values.ElementAt(LastChunk.FontIndex))
    268. RightWidth = RightWidth * TransformationValue
    269. End If
    270. 'LeftWidth is the text width at left we need to exclude, FirstChunk.distParallelStart is the distance to left margin, both together will give us this LeftOffset
    271. Dim LeftOffset As Single = FirstChunk.distParallelStart + LeftWidth
    272. 'RightWidth is the text width at right we need to exclude, FirstChunk.distParallelEnd is the distance to right margin, we substract RightWidth from distParallelEnd to get RightOffset
    273. Dim RightOffset As Single = LastChunk.distParallelEnd - RightWidth
    274. 'Return this Rectangle
    275. Return New iTextSharp.text.Rectangle(LeftOffset, FirstChunk.PosBottom, RightOffset, FirstChunk.PosTop)
    276. End Function
    277. Private Function GetStringWidth(ByVal str As String, ByVal curFontSize As Single, ByVal pSingleSpaceWidth As Single, ByVal pFont As DocumentFont) As Single
    278. Dim chars() As Char = str.ToCharArray()
    279. Dim totalWidth As Single = 0
    280. Dim w As Single = 0
    281. For Each c As Char In chars
    282. w = pFont.GetWidth(c) / 1000
    283. totalWidth += (w * curFontSize + Me.UndercontentCharacterSpacing) * Me.UndercontentHorizontalScaling / 100
    284. Next
    285. Return totalWidth
    286. End Function
    287. Private Sub DumpState()
    288. For Each location As TextChunk In locationalResult
    289. location.PrintDiagnostics()
    290. Console.WriteLine()
    291. Next
    292. End Sub
    293. Public Overridable Sub RenderText(ByVal renderInfo As TextRenderInfo) Implements ITextExtractionStrategy.RenderText
    294. Dim segment As LineSegment = renderInfo.GetBaseline()
    295. Dim location As New TextChunk(renderInfo.GetText(), segment.GetStartPoint(), segment.GetEndPoint(), renderInfo.GetSingleSpaceWidth())
    296. With location
    297. 'Chunk Location:
    298. Debug.Print(renderInfo.GetText)
    299. .PosLeft = renderInfo.GetDescentLine.GetStartPoint(Vector.I1)
    300. .PosRight = renderInfo.GetAscentLine.GetEndPoint(Vector.I1)
    301. .PosBottom = renderInfo.GetDescentLine.GetStartPoint(Vector.I2)
    302. .PosTop = renderInfo.GetAscentLine.GetEndPoint(Vector.I2)
    303. 'Chunk Font Size: (Height)
    304. .curFontSize = .PosTop - segment.GetStartPoint()(Vector.I2)
    305. 'Use Font name and Size as Key in the SortedList
    306. Dim StrKey As String = renderInfo.GetFont.PostscriptFontName & .curFontSize.ToString
    307. 'Add this font to ThisPdfDocFonts SortedList if it's not already present
    308. If Not ThisPdfDocFonts.ContainsKey(StrKey) Then ThisPdfDocFonts.Add(StrKey, renderInfo.GetFont)
    309. 'Store the SortedList index in this Chunk, so we can get it later
    310. .FontIndex = ThisPdfDocFonts.IndexOfKey(StrKey)
    311. End With
    312. locationalResult.Add(location)
    313. End Sub
    314. '*
    315. ' * Represents a chunk of text, it's orientation, and location relative to the orientation vector
    316. '
    317. Public Class TextChunk
    318. Implements IComparable(Of TextChunk)
    319. '* the text of the chunk
    320. Friend text As [String]
    321. '* the starting location of the chunk
    322. Friend startLocation As Vector
    323. '* the ending location of the chunk
    324. Friend endLocation As Vector
    325. '* unit vector in the orientation of the chunk
    326. Friend orientationVector As Vector
    327. '* the orientation as a scalar for quick sorting
    328. Friend orientationMagnitude As Integer
    329. '* perpendicular distance to the orientation unit vector (i.e. the Y position in an unrotated coordinate system)
    330. ' * we round to the nearest integer to handle the fuzziness of comparing floats
    331. Friend distPerpendicular As Integer
    332. '* distance of the start of the chunk parallel to the orientation unit vector (i.e. the X position in an unrotated coordinate system)
    333. Friend distParallelStart As Single
    334. '* distance of the end of the chunk parallel to the orientation unit vector (i.e. the X position in an unrotated coordinate system)
    335. Friend distParallelEnd As Single
    336. '* the width of a single space character in the font of the chunk
    337. Friend charSpaceWidth As Single
    338. Private _PosLeft As Single
    339. Private _PosRight As Single
    340. Private _PosTop As Single
    341. Private _PosBottom As Single
    342. Private _curFontSize As Single
    343. Private _FontIndex As Integer
    344. Public Property FontIndex As Integer
    345. Get
    346. Return _FontIndex
    347. End Get
    348. Set(ByVal value As Integer)
    349. _FontIndex = value
    350. End Set
    351. End Property
    352. Public Property PosLeft As Single
    353. Get
    354. Return _PosLeft
    355. End Get
    356. Set(ByVal value As Single)
    357. _PosLeft = value
    358. End Set
    359. End Property
    360. Public Property PosRight As Single
    361. Get
    362. Return _PosRight
    363. End Get
    364. Set(ByVal value As Single)
    365. _PosRight = value
    366. End Set
    367. End Property
    368. Public Property PosTop As Single
    369. Get
    370. Return _PosTop
    371. End Get
    372. Set(ByVal value As Single)
    373. _PosTop = value
    374. End Set
    375. End Property
    376. Public Property PosBottom As Single
    377. Get
    378. Return _PosBottom
    379. End Get
    380. Set(ByVal value As Single)
    381. _PosBottom = value
    382. End Set
    383. End Property
    384. Public Property curFontSize As Single
    385. Get
    386. Return _curFontSize
    387. End Get
    388. Set(ByVal value As Single)
    389. _curFontSize = value
    390. End Set
    391. End Property
    392. Public Sub New(ByVal str As [String], ByVal startLocation As Vector, ByVal endLocation As Vector, ByVal charSpaceWidth As Single)
    393. Me.text = str
    394. Me.startLocation = startLocation
    395. Me.endLocation = endLocation
    396. Me.charSpaceWidth = charSpaceWidth
    397. Dim oVector As Vector = endLocation.Subtract(startLocation)
    398. If oVector.Length = 0 Then
    399. oVector = New Vector(1, 0, 0)
    400. End If
    401. orientationVector = oVector.Normalize()
    402. orientationMagnitude = CInt(Math.Truncate(Math.Atan2(orientationVector(Vector.I2), orientationVector(Vector.I1)) * 1000))
    403. Dim origin As New Vector(0, 0, 1)
    404. distPerpendicular = CInt((startLocation.Subtract(origin)).Cross(orientationVector)(Vector.I3))
    405. distParallelStart = orientationVector.Dot(startLocation)
    406. distParallelEnd = orientationVector.Dot(endLocation)
    407. End Sub
    408. Public Sub PrintDiagnostics()
    409. Console.WriteLine("Text (@" & Convert.ToString(startLocation) & " -> " & Convert.ToString(endLocation) & "): " & text)
    410. Console.WriteLine("orientationMagnitude: " & orientationMagnitude)
    411. Console.WriteLine("distPerpendicular: " & distPerpendicular)
    412. Console.WriteLine("distParallel: " & distParallelStart)
    413. End Sub
    414. '*
    415. ' * @param as the location to compare to
    416. ' * @return true is this location is on the the same line as the other
    417. '
    418. Public Function SameLine(ByVal a As TextChunk) As Boolean
    419. If orientationMagnitude <> a.orientationMagnitude Then
    420. Return False
    421. End If
    422. If distPerpendicular <> a.distPerpendicular Then
    423. Return False
    424. End If
    425. Return True
    426. End Function
    427. '*
    428. ' * Computes the distance between the end of 'other' and the beginning of this chunk
    429. ' * in the direction of this chunk's orientation vector. Note that it's a bad idea
    430. ' * to call this for chunks that aren't on the same line and orientation, but we don't
    431. ' * explicitly check for that condition for performance reasons.
    432. ' * @param other
    433. ' * @return the number of spaces between the end of 'other' and the beginning of this chunk
    434. '
    435. Public Function DistanceFromEndOf(ByVal other As TextChunk) As Single
    436. Dim distance As Single = distParallelStart - other.distParallelEnd
    437. Return distance
    438. End Function
    439. '*
    440. ' * Compares based on orientation, perpendicular distance, then parallel distance
    441. ' * @see java.lang.Comparable#compareTo(java.lang.Object)
    442. '
    443. Public Function CompareTo(ByVal rhs As TextChunk) As Integer Implements System.IComparable(Of TextChunk).CompareTo
    444. If Me Is rhs Then
    445. Return 0
    446. End If
    447. ' not really needed, but just in case
    448. Dim rslt As Integer
    449. rslt = CompareInts(orientationMagnitude, rhs.orientationMagnitude)
    450. If rslt <> 0 Then
    451. Return rslt
    452. End If
    453. rslt = CompareInts(distPerpendicular, rhs.distPerpendicular)
    454. If rslt <> 0 Then
    455. Return rslt
    456. End If
    457. ' note: it's never safe to check floating point numbers for equality, and if two chunks
    458. ' are truly right on top of each other, which one comes first or second just doesn't matter
    459. ' so we arbitrarily choose this way.
    460. rslt = If(distParallelStart < rhs.distParallelStart, -1, 1)
    461. Return rslt
    462. End Function
    463. '*
    464. ' *
    465. ' * @param int1
    466. ' * @param int2
    467. ' * @return comparison of the two integers
    468. '
    469. Private Shared Function CompareInts(ByVal int1 As Integer, ByVal int2 As Integer) As Integer
    470. Return If(int1 = int2, 0, If(int1 < int2, -1, 1))
    471. End Function
    472. End Class
    473. '*
    474. ' * no-op method - this renderer isn't interested in image events
    475. ' * @see com.itextpdf.text.pdf.parser.RenderListener#renderImage(com.itextpdf.text.pdf.parser.ImageRenderInfo)
    476. ' * @since 5.0.1
    477. '
    478. Public Sub RenderImage(ByVal renderInfo As ImageRenderInfo) Implements IRenderListener.RenderImage
    479. ' do nothing
    480. End Sub
    481. End Class
    482. End Module



    aufgrund des Datenumfangs Spoiler hinzugefügt ~VaporiZed
    Bilder
    • Test.png

      76,22 kB, 1.080×764, 76 mal angesehen

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „VaporiZed“ ()

    :thumbdown: Der Sinn des Forums ist nicht, dass wir Unmengen Code bekommen und einfach mal durchschauen, wie man das Programm zum Laufen bekommt, sondern dass der Fokus auf ein Problem gesetzt wird und wir versuchen können, das anzugehen.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    @fiedel93felix PDFs sind eine sehr inhomogene Aneinanderreihung von diversen Objekten, insbesondere, wenn Tabellen im Spiel sind.
    Probier mal, in mehreren PDFs gleicher äußerer Struktur, und wenn möglich, unterschiedlicher Quellen, gleiche innere Objekte zu identifizieren.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Hallo nochmal an alle,

    ich wollte das Thema nochmal aufgreifen weil mir meine aktuelle Lösung nicht hundertprozentig gefällt.
    Aktuell arbeite ich über eine zusätzliche .dll die mir die Bearbeitung der PDF ermöglicht aber diese macht immer mal wieder Ärger.

    Ich würde das ersetzen der Texte in einer PDF gern komplett ohne zusätzlichen Tool machen.
    Ich weiß allerding nicht wo ich da anfangen soll, hat das jemand schonmal gewagt und kann mir hier weiter helfen?


    MfG Felix
    Nimm eine andere Bibliothek, wenn die nicht passt.
    Es dauert teils Jahre sich in diese Formate so einzuarbeiten, bis man alle Nuancen raus hat.

    Lass das die Profis machen und profitiere von deren Arbeit.
    Quellcode lizensiert unter CC by SA 2.0 (Creative Commons Share-Alike)

    Meine Firma: Procyon Systems
    Meine Privatwebseite: SimonC.eu

    Bitte nicht wundern, wenn meine Aktivitäten im Forum etwas langsamer sind, ich baue gerade mein Nebengewerbe zum Vollgewerbe aus.
    Ich versuche auf euch zurückzukommen :)
    @Coldfire Man könnte per WinRT die Seiten einer PDF im Speicher zu Bilder konvertieren und auch per WinRT eine OCR drüber laufen lassen die Dir den Text, die Position und Dimension der Wörter usw. zurück gibt. Mit den entsprechenden Angaben könnte man das Wort / den Text auf dem Bild überzeichnen. Am Ende jagst die Bilder über den PrintToPdf-Drucker und bekommst wieder eine PDF. Wie gesagt, könnte man. Nachteil: Die Qualität der neu erzeugten PDF wird unter Umständen schlechter und das ist, bei technischen Zeichnungen, eher nicht gewünscht bzw gibt es auch andere Nachteile wie zb Text ist nun kein Text mehr sondern ein Pixelhaufen auf einem Bild. Da wäre die direkte Bearbeitung des Textes zb per ITextSharp oder anderer Anbieter eher sinnvoller.
    Mfg -Franky-