imread und figsave - Probleme mit der Auflösung

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Pittan
User
Beiträge: 34
Registriert: Freitag 1. August 2014, 15:56

Hallo,

mit der Funktion imread() lese ich eine Bilddatei ein und füge mittels plt.tex() einige Zahlenwerte auf diesem Bild ein. Anschließend möchte ich das Bild (unter anderem Namen natürlich) wieder speichern - und zwar in der gleichen Auflösung und den gleichen Ausschnitt wie das original das ich mittels imread() eingelesen habe.
Wenn ich über plt.show() alles ausgeben lasse, sieht es zunächst ganz gut aus. Klicke ich dann aber auf "Save the figure" wird das Bild in einer ganz anderen Auflösung gespeichert und es wird sehr viel weißer Rand dem originalbild hinzugefügt.

Wie kann ich dieses Problem umgehen? Quasi so, dass nur meinem Original-Bild der Text hinzugefügt wird und in der gleichen Auflösung/Ausschnitt gespeichert wird?

Danke
Gruß
Pittan
User
Beiträge: 34
Registriert: Freitag 1. August 2014, 15:56

*push*

keiner eine idee? :K
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

@Pittan: Matplotlib ist wie der Name schon sagt, eine mathematische Zeichnungsbibliothek. Um Bilder zu bearbeiten brauchst Du eine Pythonische Bilderbibliothek, sprich PIL, nka Pillow.
Pittan
User
Beiträge: 34
Registriert: Freitag 1. August 2014, 15:56

Hi,

vielen Dank zunächst für deine Antwort.
Prinzipiell führen immer viele Wege nach Rom. Ich selber habe leider nicht sehr viel Erfahrung mit Python, mit Matplotlib habe ich auf anraten meines Professors gearbeitet. Das funktioniert auch, bis auf diese Kleinigkeit.

Wenn Python bzw. Matplotlib das Diagramm öffnet, sieht es so aus (und so soll es auch aussehen):
Bild

Klickt man anschließend auf speichern (button oben), sieht es dann so aus (und so soll es nicht aussehen)
Bild
Die Abmessungen des Bildes sind viel zu hoch


Gibt es eine Funktion in Matplotlib, welche wirklich nur das dargestellte Diagramm speichert?

Gruß
BlackJack

@Pittan: Also ich kann mir gerade nur das erste Bild direkt auf Dropbox anschauen, aber willst Du tatsächlich Text in eine Grafik einfügen die überhaupt nichts mit Diagrammen o.ä. zu tun hat, sondern eher wie ein Formular aussieht? Dazu ist Matplotlib vielleicht wirklich nicht das passende Werkzeug.

Das dargestellte Diagramm kann im Grunde nicht gespeichert werden. Matplotlib arbeitet mit verschiedenen Backends. Zum Beispiel eines um die Diagramme in einer GUI anzuzeigen, eines für PDF, eines für SVG, und auch eines für Grafiken. Das Diagramm wird für jedes dieser Backends separat aus dem entsprechenden Objekt erstellt. Bein Speichern wird also nicht die im Fenster angezeigte Grafik abgespeichert, sondern das Diagramm welches für das Fenster durch ein Backend aufbereitet wurde, wird mit dem Backend für Bilddateien erneut im Speicher erstellt und dann als Bilddatei gespeichert. Dabei kann es dann natürlich zu Unterschieden in der Darstellung kommen.
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

@Pittan: das Bild ist doch genau das was Du laut Bildschirmausgabe auch willst, nur dass der Hintergrund des Fensters halt grau, das des Bildes weiß ist. Das sind eben andere default-Einstellungen, weil auf einem Drucker ausgedruckt die meisten sich an einem grauen Rand stören. Sowas will ich persönlich aber weder als Bitmap noch mit Matplotlib haben; so wie es aussieht, kommt es von einer Excel-Vorlage, die man am besten auch nimmt, um die Zahlen aufzufüllen und danach als PDF druckt. Daneben könnte man auch eines der vielen PDF-Tools nehmen, um daraus ein Formular zu machen, um das dann auszufüllen.
Was ist denn Deine eigentliche Aufgabe? Warum muß das Formular ausgefüllt werden, wie soll es weiter verarbeitete werden?
Pittan
User
Beiträge: 34
Registriert: Freitag 1. August 2014, 15:56

Hallo,
das Formular kommt aus einer DIN-Norm und muss ausgefüllt werden. Die Berechnungen dazu habe ich in Python (mit Numpy) umgesetzt und möchte jetzt die Ergebnisse auf dem Bitmap stehen haben.
Offenbar ist mein Prof. ein Idiot. Er hat es mir mit empfohlen, mit Matplotlib umzusetzen.
Welche andere Möglichkeit hätte ich denn?

Schönen Gruß
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

@Pittan: Leute empfehlen das, was sie kennen. Deshalb ist man noch lange kein Idiot. Wer trotz besseren Wissens auf seiner Meinung beharrt, kann man als Idiot bezeichnen.

So: Ich kann ja nochmal meine letzten Posts hier kopieren. :twisted:

1. Woher hast Du die Vorlage? Excel? PDF? Das ganze als Bitmap zu bearbeiten halte ich für quatsch, es sei denn ...
2. was soll damit gemacht werden? Muß es wirklich ein Bitmap sein?
Pittan
User
Beiträge: 34
Registriert: Freitag 1. August 2014, 15:56

Hi,

die Vorlage kommt aus einem pdf - daraus habe ich mir ein png erzeugt.

Da anschließend diese Formulare in einer Wissenschaftlichen Arbeit verwendet werden, ist die weiterverwendung als png das beste, da man dieses png einfach in die Arbeit einfügen kann.

Schönen Gruß
BlackJack

@Pittan: Für so etwas ist ein pixelbasiertes Format ganz sicher nicht das beste. Das erhöht in der Regel die Datenmenge, wobei Informationen verlorengehen die im PDF noch enthalten sind, weil ja alles auf Pixel reduziert wird, und man nimmt sich die Flexibilität bezüglich der Auflösung des Endproduktes, sei das nun so etwas wie PDF oder ein Ausdruck.

Bei einer wissenschaftlichen Arbeit würde ich ja zum Beispiel auf LaTeX setzen und da ist das einbinden von PDFs kein Problem. Im Gegenteil ist das ein Vektorformat was sich dort sehr gut einbinden lässt, insbesondere wenn das Ausgabeziel selbst PDF ist.

Wenn ich eine andere Textverarbeitung verwenden müsste, würde ich das PDF-Formular wahrscheinlich in Inkscape importieren und als SVG speichern. Da kann man dann auch Platzhalter für Texte einfügen die man dann programmatisch mit Werten füllen kann.
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

@Pittan: da ich aus der Digitalsatz-Ecke komme, tut mir das was Du schreibst in den Ohren weh. Wahrscheinlich schreibst Du Deine Wissenschaftlichen Arbeiten mit Word. Zum Glück muß ich mit dem Ergebnis nicht meine Augen quälen. Missionieren ist vergebliche Liebesmühe.
Die Lösung steht bereits in meinem ersten Post. Die Dokumentation hat genug Beispiele.
Pittan
User
Beiträge: 34
Registriert: Freitag 1. August 2014, 15:56

Sirius und Blackjack,

ich möchte eure Kompetenz wirklich nicht in Frage stellen. In einigen Punkten wurde mir hier auch wirklich weiter geholfen.
Ich denke aber, ihr erkennt nicht das wahre Problem:
Ich bin Maschinenbauingenieur - kein Programmierer oder dergleichen. Bei meiner Arbeit konzentriere ich mich auf den wissenschaftlichen Inhalt. Ich habe weder Zeit, noch Muße, mich in Latex, PIL oder dergleichen einzuarbeiten. Und die Programmiersprache Python soll mich unterstützen bei meiner Arbeit. Wenn ich nun noch einen 3 Monatigen Python-Mega-Crack-Kurs absolviere, könnte ich von vorn hinein gleich alles mit Stift-und-Papier machen.

Nimmt das nicht als Kritik an, sondern einfach nur als meine Sicht auf die Dinge.
Natürlich gibt es immer eine bessere Möglichkeit - mir als Ingenieur ist das durchaus bewusst. Aber man muss auch den Blick bewahren für das Kosten-Nutzen-Verhältnis.

Schönen Gruß
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

@Pittan: Du willst Dich in MatplotLib einarbeiten aber nicht in PIL???
Auch von einem Maschinenbauingenieur erwarte ich, dass er in der Lage ist, eine Dokumentation zu überfligen, sich die relevanten Abschnitte durchzulesen und sich anhand von Beispielen klar zu machen, wie er es benutzen soll.
BlackJack

@Pittan: In *irgend etwas* musst Du Dich ja einarbeiten um die Grafik zu manipulieren. Mit Stift und Papier kannst Du es ja schon deswegen nicht machen weil es ja automatisiert und wiederholbar sein soll. Sonst könntest Du es in der Tat manuell machen, mit einem entsprechenden Grafikprogramm. Wobei auch dort Pixelgrafik die deutlich schlechtere Lösung ist. Klar gibt es immer bessere Möglichkeiten, die mit hörerem Aufwand verbunden sind, aber hier reden wir von IMHO sehr ähnlichem Aufwand, und dann macht es wenig Sinn die schlechtere Variante zu wählen.

Ich würde wie gesagt den Weg über SVG versuchen. Inkscape, ein freier Vektorgrafikeditor, kann Seiten aus PDF-Dokumenten importieren. Das ”native” Format ist SVG, ein auf XML basierender Webstandard. Man kann dann auf der importierten Seite Texte platzieren wo man per Programm dann die Werte einfügen möchte und diesen Textgrafikobjekten eine ID vergeben, über die man das XML-Element programmatisch leicht identifizieren/ansteuern kann. Das ist bis hier alles ganz einfach per Maus in einer grafischen Oberfläche zu machen.

Wenn man die Seite als SVG-Datei gespeichert hat, kann man diese mit einer entsprechenden Bibliothek in einem Python-Programm laden, die Elemente anhand der IDs suchen, den Text ersetzen, und wieder als SVG speichern.

Der Knackpunkt ist dann die Textverarbeitung, ob die SVG lesen und einbetten kann. Das würde ich allerdings erwarten, weil SVG wie gesagt ein Webstandard ist. Ansonsten müsste man das noch in ein Vektorformat umwandeln welches die Textverarbeitung versteht. Inkscape kann auch in ein paar anderen Formaten speichern und man kann Inkscape auch ohne GUI aufrufen um zum Beispiel eine Datei zu konvertieren. Das liesse sich notfalls also auch von einem Python-Programm aus tun.
Pittan
User
Beiträge: 34
Registriert: Freitag 1. August 2014, 15:56

Hallo,

danke schonmal für die Antworten.
Ich denke PIL scheint passender für mich zu sein - auch wenn die Lösung von Blackjack eleganter klingt.

Mit PIL habe ich aber derzeit ein Problem:

Code: Alles auswählen

import numpy as np
from PIL import Image

img=Image.open('Lueftung.png')

img.show()
Wenn ich diesen Code auf meinem Laptop ausführe, funktioniert alles ganz wunderbar.
Auf meinem PC erscheint aber folgende fehlermeldung:

Code: Alles auswählen

Die Datei "'c:\users\pittan\appdata\local\temp\tmptiof5t.BMP'" kann nicht gefunden werden.

Woher kommt diese Fehlermeldung? Warum funktioniert es auf meinem Laptop, aber nicht auf meinem Pc?

PS: Und dies ist genau der Grund, warum ich nicht mit anderen Werkzeugen arbeiten möchte, als mir das Institut vorgibt. Nachher läuft auf meinem Rechner alles perfekt, aber im Institut läuft gar nichts und ich bin durchgefallen - weil ich unbedingt die beste und eleganteste Lösung haben wollte...
BlackJack

@Pittan: `show()` schreibt das Bild in eine temporäre Datei und verwendet ein externes Programm zum anzeigen. Anscheinend gibt es dabei Probleme. Die Methode ist laut Pillow-Dokumentation (Image.show()) auch hauptsächlich zur Fehlersuche gedacht, also weniger um in einem Programm tatsächlich die Bilder anzuzeigen.

Das gleiche kann Dir auch mit den vom Institut vorgegebenen Werkzeugen passieren, das etwas auf Deinem Rechner läuft und im Institut wegen unterschiedlicher Versionen, Einstellungen, oder anderer Rahmenbedingungen nicht. Oder umgekehrt.
Pittan
User
Beiträge: 34
Registriert: Freitag 1. August 2014, 15:56

Hi Blackjack,

danke für den Hinweis.
Das Programm, dass ich schreibe, soll aber bei Ausführung genau die Bilder anzeigen. Daher verwende ich img.show()

Ein anderes Problem: ImageDraw.text verlangt als übergabe einen String, der auf dem Bild gezeigt wird.
Ich will aber keinen String übergeben, sondern die Variablen, deren Inhalt gezeigt werden soll.

Leider finde ich dazu keinen Hinweis. Funktioniert das überhaupt mit ImageDraw.text?

Danke
Gruß
BlackJack

@Pittan: Nein, diese Methode funktioniert dann nur mit literalen Zeichenketten. :twisted:

Wenn da Zeichenkette in der Dokumentation steht, dann ist natürlich jeder Ausdruck gemeint der zu einer Zeichenkette ausgewertet wird und nicht nur literale Zeichenketten. Das ist ja in etwa so als würdest Du fragen ob man mit `math.sin()` nur den Sinus von Gleitkommaliteralen berechnen kann, und nicht auch von ”Variablen” oder gar Rechenoperationen. Eine Funktion hat doch auch überhaupt gar keine direkt vorgesehene Möglichkeit überhaupt heraus zu finden wie ein Argumentwert zustande gekommen ist. Das geht die Funktion auch überhaupt nichts an.

Edit: Kleine Suche („PIL Image show() windows file not found”) ergibt übrigens dass das unter Windows Vista/Windows 7 ein grundsätzliches Problem mit PIL zu sein scheint. Ich würde als erstes prüfen ob Pillow das Problem auch hat, denn das wird ja aktiv weiter entwickelt.
Pittan
User
Beiträge: 34
Registriert: Freitag 1. August 2014, 15:56

BlackJack hat geschrieben:@Pittan: Nein, diese Methode funktioniert dann nur mit literalen Zeichenketten. :twisted:

Wenn da Zeichenkette in der Dokumentation steht, dann ist natürlich jeder Ausdruck gemeint der zu einer Zeichenkette ausgewertet wird und nicht nur literale Zeichenketten. Das ist ja in etwa so als würdest Du fragen ob man mit `math.sin()` nur den Sinus von Gleitkommaliteralen berechnen kann, und nicht auch von ”Variablen” oder gar Rechenoperationen. Eine Funktion hat doch auch überhaupt gar keine direkt vorgesehene Möglichkeit überhaupt heraus zu finden wie ein Argumentwert zustande gekommen ist. Das geht die Funktion auch überhaupt nichts an.

Edit: Kleine Suche („PIL Image show() windows file not found”) ergibt übrigens dass das unter Windows Vista/Windows 7 ein grundsätzliches Problem mit PIL zu sein scheint. Ich würde als erstes prüfen ob Pillow das Problem auch hat, denn das wird ja aktiv weiter entwickelt.
Genau das habe ich gemeint! Nun habe ich 1 1/2 Tage Arbeitszeit verschwendet für eine S* die mir am Ende gar nichts gebracht hat.
Und der Inhalt meiner Arbeit ist es nicht, möglichst elegant und schön zu programmieren und wahnsinnig tolle Bildchen zu erzeugen - sondern wissenschaftliche, energietechnische Erkentnisse zu produzieren.
Dementsprechend habe ich wenig Lust unmengen an Energie zu verschwenden dieses kac* PIL, PILLOW, Inkscape oder sonstwas fuer einen Mist zu lernen.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Du kannst es doch einfach selbst in eine temporäre Datei schreiben und dann nen Bildbetrachter ausführen, sehe jetzt nicht so das große Problem.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Antworten