2016-06-28 17 views
2

Ich habe eine Reihe von PDFs, die ich in Text konvertieren möchte. Es ist einfach, den Text mit so etwas wie diesem von iTextSharp zu bekommen:C# Pdf zu Text mit Bild Platzhalter

PdfTextExtractor.GetTextFromPage(reader, pageNumber); 

Es ist einfach, Bilder mit this answer (oder ähnlichen Antworten im Thread) zu erhalten.

Was ich nicht leicht herausfinden kann ... ist, wie Bild Platzhalter im Text verschachtelt werden.

eine PDF, eine Seite # und GetTextFromPage ich die Ausgabe zu erwarten Gegeben:

line 1 
line 2 
line 3 

Als ich es (Wo 1.1 bedeutet, Seite 1, Bild 1 ... Seite 1 sein möchte, Bild 2):

line 1 
[1.1] 
line 2 
[1.2] 
line 3 

gibt es eine Möglichkeit, einen „Bild-Platzhalter“ für iTextSharp, PDFsharp oder ähnliches zu bekommen? Ich hätte gerne eine GetTextAndPlaceHoldersFromPage Methode (oder ähnliches).

PS: Hrm ... es lässt mich nicht iTextSHARP - nicht iText. C# nicht Java.

+0

Suchen Sie so etwas wie die Lösung für iText/Java in [dieser Antwort] (http://stackoverflow.com/a/28087521/1729265)? Es sollte leicht in iTextSharp/C# übersetzt werden. – mkl

+0

@mkl aktualisierte Erklärung, um diese Frage näher zu entsprechen. Ich dachte darüber nach, mich ein bisschen wie gestern Abend auszudehnen. Diese Frage ist im Grunde genommen die gleiche, außer dass ich in C# mit iTextSharp arbeite (obwohl ich nicht abgeneigt bin, wenn nötig in andere Bibliotheken wie PdfSharp zu wechseln). – WernerCD

+0

So könnte man erstellen, was Sie wollen, indem Sie die iText/Java-Lösung von dieser alten Frage zu iTextSharp/C# portieren. Das sollte nicht zu schwer sein ... – mkl

Antwort

1

C# Pdf to Text with image placeholder
https://stackoverflow.com/a/28087521/
https://stackoverflow.com/a/33697745/

Obwohl dies nicht das genaue Layout in meiner Frage erwähnt hat (Da, dass eine vereinfachte Version war das, was ich wirklich wollte sowieso), hat es die Ausgangsteile haben als aufgelistet durch die zweite Notiz (übersetzt aus iText Java) ... mit zusätzlichen Informationen aus der dritten Notiz (Einige der in Java verwendeten Reflektionen schienen in C# nicht zu funktionieren, so dass die Informationen aus # 3 kamen).

Davon ausgehend kann ich eine Liste von Strings erhalten, die Linien in der PDF darstellen (alle Seiten statt nur Seite 1) ... mit Text hinzugefügt, wo Bilder sein sollten (Huzzah!). Die ByteArrayToFile-Erweiterungsmethode wurde für den Geschmack hinzugefügt (obwohl ich keine anderen Teile/Erweiterungen hinzugefügt habe, die den Code kopieren/einfügen könnten).

Ich war auch in der Lage, andere Teile meines Prozesses und gut Hälfte des Mülls, den ich vorher gearbeitet hatte, stark zu vereinfachen. Huzzah !!! @Mkl Dank

internal class Program 
{ 
    public static void Main(string[] args) 
    { 
     var dir = Settings.TestDirectory; 
     var file = Settings.TestFile; 

     Log.Info($"File to Process: {file.FullName}"); 

     using (var reader = new PdfReader(file.FullName)) 
     { 
      var parser = new PdfReaderContentParser(reader); 
      var listener = new SimpleMixedExtractionStrategy(file, dir); 
      parser.ProcessContent(1, listener); 
      var x = listener.GetResultantText().Split('\n'); 
     } 
    } 
} 

public class SimpleMixedExtractionStrategy : LocationTextExtractionStrategy 
{ 
    public static readonly ILog Log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 
    public DirectoryInfo OutputPath { get; } 
    public FileInfo OutputFile { get; } 

    private static readonly LineSegment UNIT_LINE = new LineSegment(new Vector(0, 0, 1), new Vector(1, 0, 1)); 
    private int _counter; 

    public SimpleMixedExtractionStrategy(FileInfo outputFile, DirectoryInfo outputPath) 
    { 
     OutputPath = outputPath; 
     OutputFile = outputFile; 
    } 

    public override void RenderImage(ImageRenderInfo renderInfo) 
    { 
     try 
     { 
      var image = renderInfo.GetImage(); 
      if (image == null) return; 
      var number = _counter++; 

      var imageFile = new FileInfo($"{OutputFile.FullName}-{number}.{image.GetFileType()}"); 
      imageFile.ByteArrayToFile(image.GetImageAsBytes()); 

      var segment = UNIT_LINE.TransformBy(renderInfo.GetImageCTM()); 
      var location = new TextChunk("[" + imageFile + "]", segment.GetStartPoint(), segment.GetEndPoint(), 0f); 
      var locationalResultField = typeof(LocationTextExtractionStrategy).GetField("locationalResult", BindingFlags.NonPublic | BindingFlags.Instance); 
      var LocationalResults = (List<TextChunk>)locationalResultField.GetValue(this); 
      LocationalResults.Add(location); 
     } 
     catch (Exception ex) 
     { 
      Log.Debug($"{ex.Message}"); 
      Log.Verbose($"{ex.StackTrace}"); 
     } 
    } 
} 

public static class ByteArrayExtensions 
{ 
    public static bool ByteArrayToFile(this FileInfo fileName, byte[] byteArray) 
    { 
     try 
     { 
      // Open file for reading 
      var fileStream = new FileStream(fileName.FullName, FileMode.Create, FileAccess.Write); 

      // Writes a block of bytes to this stream using data from a byte array. 
      fileStream.Write(byteArray, 0, byteArray.Length); 

      // close file stream 
      fileStream.Close(); 

      return true; 
     } 
     catch (Exception exception) 
     { 
      // Error 
      Log.Error($"Exception caught in process: {exception.Message}", exception); 
     } 

     // error occured, return false 
     return false; 
    } 
}