Laden...

Bilder aus PDF extrahieren und benennen - iText7

Erstellt von illogic vor 2 Jahren Letzter Beitrag vor 2 Jahren 628 Views
I
illogic Themenstarter:in
3 Beiträge seit 2021
vor 2 Jahren
Bilder aus PDF extrahieren und benennen - iText7

Hallo,

ich bin neu in diesem Forum und auch mit der C# Programmierung beschäftige ich mich erst seit wenigen Monaten.
Nun stehe ich jedoch beruflich vor einer kleinen Herausforderung, die ich gerne programmatisch lösen möchte.
Hierzu würde ich zuvor gerne ein paar Vorschläge und Lösungsansätze von erfahreneren Programmierern einholen.

Zunächst einmal das Problem:
• Ich arbeite mit PDF Dokumenten
• Diese PDF Dokumente enthalten ab Seite 2, auf jeder Seite jeweils immer 2 Bilder.
• Diese 2 Bilder sind immer in der selben Reihenfolge angeordnet, da diese von einer App eines Messgerätes generiert werden.
• Bei den Bildern handelt es sich also um Aufzeichnungen einer Messung, und zwar ein Pegelschrieb und ein Spektrogramm.
• Oberhalb der beiden Bilder ist eine Notiz angegeben. Der Bezeichner für das gemessene Objekt.
• Diese Bilder müsste ich aus dem PDF extrahieren und als Bitmap abspeichern (.jpg etc.).
• Die Dateien müssten jeweils als Dateinamen den auf der PDF Seite aufgeführten Bezeichner als Dateinamen erhalten.
• Da der Bezeichner für beide Bilddateien gleich wäre, brauchen die Bilder eine Erweiterung im Dateinamen (_pgs für Pegelschrieb, _spg für Spektrogramm).

Das Programm müsste quasi nach und nach jede PDF Seite durchlaufen, die beiden Bilder extrahieren und mit dem jeweiligen Bezeichner versehen.
Jetzt ist meine Frage, wer kennt sich mit so etwas aus und hat eine Idee mit welcher Library das möglich wäre? (Opensource würde ich vorziehen)
Kennt sich jemand mit iText7 Core aus? Würde das funktionieren oder gibt es noch andere Alternativen?

Da ich noch recht unerfahren in der C# Programmierung bin, kenne ich mich in diesem Punkt noch nicht so gut aus.

Vielen Dank im Voraus und sorry für den langen Text 😉
P.S.: Ich habe eine PDF Datei angehängt, falls sich jemand ein bild davon machen möchte.

Gruß
Manuel

P
441 Beiträge seit 2014
vor 2 Jahren

Hi,

was hast du denn bisher probiert? Das Forum ist dazu da dir bei konkreten Problemstellungen zu helfen, nicht dir ein Programm zu schreibem.
Ich habe vor Jahren mal mit iText gearbeitet, soweit ich mich erinnere könnte das funktionieren.

I
illogic Themenstarter:in
3 Beiträge seit 2021
vor 2 Jahren

Hallo, so ist das posting auch nicht zu interpretieren. Mir soll niemand ein Programm schreiben. Ich versuche nur abzuklopfen ob ich mit der Library diesbezüglich auf einem guten weg bin.
Die Frage hast mir ja ansich beantwortet. Ich poste die Tage was ich erreicht habe. Kann aber ein wenig dauern, da ich wenig Zeit habe und wie gesagt eher neuling in C#. =)

16.834 Beiträge seit 2008
vor 2 Jahren

Joa, da hat Papst schon recht: so liest sich Dein Post nicht so.
Ein Forum kann Dir bei konkreten Problemen gut helfen; da ist das ein gutes Medium - aber Du musst dazu auch eine konkrete Frage stellen oder das Problem beschreiben.

Ob ein Paket Deine Aufgaben erfüllt; das musst Du evaluieren - das ist quasi Alltagsjob eines Entwicklers 🙂
PDF Bibliotheken gibt es wenig gute; und wenn, dann kosten die meistens gut Geld.
Wirklich freie Bibliotheken gibt es wenig bzw. haben einige Bibliotheken Lizenzen, die einen kommerziellen Einsatz verbieten.

Wenn ich Google Suche nach "c# pdf extract image" suche, dann gibts zumindest ein paar Treffer; darunter auch was zu iText 7 => how-to-extract-images-from-pdf-using-itext7-c-sharp

P
57 Beiträge seit 2017
vor 2 Jahren

Ganz so einfach ist das nicht ein Bild aus einem PDF zu extrahieren.

Da gibt es mehrere Möglichkeiten die auch teils recht fehlerbehaftet sind.
Bei iText7 (vormals iTextSharp) müsstest du dir das Canvas raussuchen bzw. wissen an welcher Position das Bild
platziert ist.

Es dürfte noch mit GhostScript direkt gehen - das ist dann aber nochmal eine Ecke
aufwändiger.

Abt hat da durchaus recht - die freien Bibliotheken sind zum erzeugen meistens brauchbar aber bei der
Verarbeitung von PDFs ohne Umwege für die Füße.

Im übrigen - mit welcher Sprache du arbeitest ist in dem Punkt erstmal egal - PDF verstehen ist da besser 😉.
Nicht böse gemeint aber ganz so einfach ist es halt leider nicht bei diesem Format.

.....an unhandled exception is the first way to think about your pattern of programming....
.....nur weil ich nicht weiß was dort passiert, bedeutet es nicht, dass ich nicht weiß, wie man es lösen kann - aber das ist wahrscheinlich....

M
368 Beiträge seit 2006
vor 2 Jahren

Noch ein "Alltagsjob": Alternativen in Betracht ziehen, z.B. Python i.V. mit PyMuPDF (https://www.geeksforgeeks.org/how-to-extract-images-from-pdf-in-python/) oder gleich schwereres Geschütz in Form von Adobe Acrobat Pro ( https://www.groovypost.com/howto/adobe-acrobat-pro-extract-images-from-pdf-export/ ) (ändert nichts an den bisherigen Ratschlägen)

Goalkicker.com // DNC Magazine for .NET Developers // .NET Blogs zum Folgen
Software is like cathedrals: first we build them, then we pray 😉

I
illogic Themenstarter:in
3 Beiträge seit 2021
vor 2 Jahren

So, zunächst einmal Danke für die Antworten!
Ich habe mich jetzt mal etwas mit iText 7 beschäftigt.
Inzwischen habe ich funktionierenden Code, der mir von jeder PDF Seite die beiden Bilder extrahiert und diese wie gewünscht benennt.
Das ganze ist Testweise eine einfache Konsolenapplikation.

Hier mal der Code, falls es jemanden interessiert wie es funktioniert:


    class PdfImageExtractor
    {
        static public void Main(string[] args)
        {
            string fileName = @"C:\PdfImageExtractions\SourcePdf\test.pdf";
            var imageExtractor = new PdfImageExtractor(fileName);
            imageExtractor.ExtractToDirectory(@"C:\PdfImageExtractions\ExtractedImages");
        }

        private readonly string _pdfFileName;

        public PdfImageExtractor(string pdfFileName)
        {
            _pdfFileName = pdfFileName;
        }

        public void ExtractToDirectory(string directory)
        {
            using (var reader = new PdfReader(_pdfFileName))
            {
                reader.SetUnethicalReading(true);

                using (var pdfDoc = new PdfDocument(reader))
                {
                    ExtractImages(pdfDoc, directory);
                }
            }
        }

        private void ExtractImages(PdfDocument pdfDoc, string directory)
        {
            int numberOfPages = pdfDoc.GetNumberOfPages();
            List<string> listOfPageText = new List<string>();
            string keyword = "KA";
            string targetString = string.Empty;
            string trimmedString = string.Empty;

            for (int page = 2; page <= numberOfPages; page++)
            {
                ITextExtractionStrategy textExtractionStrategy = new SimpleTextExtractionStrategy();

                string currentPageText = PdfTextExtractor.GetTextFromPage(pdfDoc.GetPage(page), textExtractionStrategy);

                if (currentPageText.Contains(keyword))
                {
                    listOfPageText = currentPageText.Trim().Split(' ').ToList();
                    targetString = listOfPageText.ElementAt(28);
                    trimmedString = targetString.GetUntilOrEmpty();
                }

                IEventListener imageExtractionStrategy = new ImageRenderListener(Path.Combine(directory, trimmedString));
                PdfCanvasProcessor parser = new PdfCanvasProcessor(imageExtractionStrategy);
                parser.ProcessPageContent(pdfDoc.GetPage(page));
            }
        }
    }

    public class ImageRenderListener : IEventListener
    {
        string format = "";
        int counter = 1;

        public ImageRenderListener(string format)
        {
            this.format = format;
        }

        public void EventOccurred(IEventData data, EventType type)
        {
            if (data is ImageRenderInfo imageData)
            {
                try
                {
                    PdfImageXObject imageObject = imageData.GetImage();

                    if (imageObject == null)
                    {
                        Console.WriteLine("Bild konnte nicht verarbeitet werden.");
                    }
                    else
                    {
                        if (counter == 1)
                        {
                            File.WriteAllBytes(string.Format(format + "_pgs.jpg", imageObject.IdentifyImageFileExtension()), imageObject.GetImageBytes());
                        }

                        else if (counter == 2)
                        {
                            File.WriteAllBytes(string.Format(format + "_spg.jpg", imageObject.IdentifyImageFileExtension()), imageObject.GetImageBytes());
                        }

                        counter++;
                    }

                }
                catch (Exception ex)
                {
                    Console.WriteLine("Bild konnte nicht verarbeitet werden: {0}.", ex.Message);
                }
            } 
        }

        public ICollection<EventType> GetSupportedEvents()
        {
            return null;
        }
    }

    static class StringHelper
    {
        public static string GetUntilOrEmpty(this string text, string stopAt = "\n")
        {
            if (!String.IsNullOrWhiteSpace(text))
            {
                int charLocation = text.IndexOf(stopAt, StringComparison.Ordinal);

                if (charLocation > 0)
                {
                    return text.Substring(0, charLocation);
                }
            }

            return String.Empty;
        }
    }

Als nächstes werde ich ein UI für eine interaktive Bedienung erstellen (FolderPicker, FilePicker etc.).

Gruß
Manuel