screenshot als Bild in PDF speichern

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.
UniversalBastler
User
Beiträge: 17
Registriert: Samstag 1. August 2020, 12:08

Hallo,
die freie Zeit während der Coronakrise nutze ich (>60) um Python zu lernen.
In diesem Forum habe ich schon einige Hilfestellungen gefunden, hierfür vielen Dank.
Jetzt habe ich allerdings eine (hoffentlich nur kleine) Frage für die ich nichts passendes gefunden habe. Vielleicht habe ich auch nur nach den falschen Begriffen gesucht.
Ich habe ein kleines Programm geschrieben das mehrere screenshots aufnimmt, zu einem PDF Dokument zusammenfasst und abspeichert.
Dazu importiere ich pyautogui und fpdf.
Es funktioniert auch soweit aber ich speichere den screenshot als .png auf der HD um ihn dann gleich wieder zu laden.
Alle Versuche den screenshot direkt wie ein Bild zu bearbeiten sind gescheitert.
Ich habe schon stundenlang im Internet gesucht aber nichts passendes gefunden dabei stelle ich mir vor, dass nur eine Kleinigkeit fehlt den sreenshot in ein Bild umzuwandeln.
Nachfolgend eine verkürzte Version meines Programms.
Es wird ein screenshot von der linken Bildschirmseite (region) gemacht und als PDF-Test2.pdf gespeichert.
Wie oben geschrieben funktioniert es aber das Zwischenspeichern stört mich.
Vielleicht weiß ja jemand den richtigen "Kniff".

Code: Alles auswählen

import pyautogui
from time import sleep
from fpdf import FPDF 

pdf = FPDF()#PDF wird erstellt

screenshot1 = pyautogui.screenshot(region=(80,48, 880, 960))#screeshot der ersten Seite (linke Hälfte)
sleep(1) #warten bist erledigt
screenshot1.save("seiteL.png")#screenshot zwischenspeichern

pdf.add_page() #Seite wird dem PDF zugefügt
seite = "seiteL.png" #screenshot (jetzt .png) wird geöffnet und seite zugewiesen
pdf.image(seite ,10 ,40, 200) #screenshot (jetzt seite) wird auf der PDF Seite positioniert

sleep(1)

pdf.output("PDF-Test2.pdf", "F") #fertiges PDF wird gespeichert
print("Fertig")
Sirius3
User
Beiträge: 18261
Registriert: Sonntag 21. Oktober 2012, 17:20

Wie bist du auf fpdf gekommen? Das wird ja nun schon seit einigen Jahren nicht weiter entwickelt. FPDF.inage erwartet einen Dateinamen. Um saß zu ändern, müsste man zwei drei Zeilen umprogrammieren.
UniversalBastler
User
Beiträge: 17
Registriert: Samstag 1. August 2020, 12:08

fpdf habe ich irgendwo im Netz gefunden und das funktioniert ja auch so wie es soll. Wie oben geschrieben, fange ich erst an mit Python. Da nimmt man was funktioniert;-)
Die Frage taucht aber auch unabhängig vom PDF erstellen auf. Den screenshot nehme ich mit pyautogui.screenshot auf. und speichere ihn mit -screenshot1.save("seiteL.png")- ab. Dadurch wandele ich den scrennshot in ein png Bild oder??? Kann ich den screenshot nicht einfach so in ein Bild wandeln? den scrennshot kann ich so wie er gemacht wird nicht bearbeiten.
Sirius3
User
Beiträge: 18261
Registriert: Sonntag 21. Oktober 2012, 17:20

Was meinst du mit "einfach so in ein Bild wandeln"? Was willst du denn machen?
UniversalBastler
User
Beiträge: 17
Registriert: Samstag 1. August 2020, 12:08

Was ich machen will habe ich oben geschrieben.
Das Problem ist glaube ich, dass pyautogui.screenshot() kein Bild in speichert sondern eher Binärdaten?
Erst durch das speichern als png wird ein Bild daraus. So stelle ich mir das jedenfalls vor.
Sirius3
User
Beiträge: 18261
Registriert: Sonntag 21. Oktober 2012, 17:20

Wie ich schon geschrieben habe, liegt es an fpdf, dass das nur mit Bilddateien arbeiten kann, nicht an pyautogui. Entweder du suchst dir einen pdf-Generator, der direkt mit den Bildobjekten die pyautogui liefert arbeiten kann, oder du schreibst fpdf um. Erstes ist nachhaltiger.
UniversalBastler
User
Beiträge: 17
Registriert: Samstag 1. August 2020, 12:08

Entweder du suchst dir einen pdf-Generator, der direkt mit den Bildobjekten die pyautogui liefert arbeiten kann
Okay, danke, jetzt habe ich das kapiert.
Wenn ich bei duckduckgo was suche bekomme ich meist fpdf bzw. PyFPDF angezeigt.
Irgend einen Vorschlag was ich stattdessen nehmen kann?
UniversalBastler
User
Beiträge: 17
Registriert: Samstag 1. August 2020, 12:08

Aber eigentlich wollte ich ja nur wissen, wie ich den pyautogui.screenshot() als .png Bild in eine Variable (hier seite) schreiben kann ohne das Bild auf der Festplatte zwischen zu speichern.
Alles andere ist wahrscheinlich zu aufwändig da das Programm ja auch so funktioniert.
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Aber wozu brauchst du da, wenn die PDF Bibliothek dann damit nichts anfangen kann?

Doch wenn’s sein soll: schau dir mal io.BytesIO an, damit sollte das gehen.
Benutzeravatar
noisefloor
User
Beiträge: 4187
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,

DAS Python-Modul zum Generieren von PDFs ist eigentlich ReportLab. Das sollte auch DuckDuckGo finden ;--)

Gruß, noisefloor
UniversalBastler
User
Beiträge: 17
Registriert: Samstag 1. August 2020, 12:08

Aber wozu brauchst du da, wenn die PDF Bibliothek dann damit nichts anfangen kann?
Die PDF Bibliothek fpdf kann ja gerade mit einem .png Bild etwas anfangen aber nicht mit dem screenshot.
Vielen Dank für den Hinweis, io.BytesIO werde ich mir anschauen.
DAS Python-Modul zum Generieren von PDFs ist eigentlich ReportLab. Das sollte auch DuckDuckGo finden ;--)
ReportLab habe ich auch gesehen, das scheint mir aber sehr aufwändig zu sein. Das fpdf funktioniert ja und ist für einen Einsteiger auch zu händeln. ReportLap ist so umfangreich, das erschlägt mich. Wenn ich mit io.BytesIO nicht weiterkomme schaue ich mir das auf jeden Fall auch noch an.
Vielen Dank bis hierher.
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Dann habe ich glaube ich immer noch nicht verstanden, was dein Problem ist. Ein Screenshot ist bei mir immer ein PNG. Wenn du das so abgrenzt zu PNG - was heißt das denn dann? Was ist denn ein screenshot , wenn kein PNG?
Sirius3
User
Beiträge: 18261
Registriert: Sonntag 21. Oktober 2012, 17:20

@__deets__: es geht darum, dass fpdf nur Bilder über den Dateinamen in pdfs einbinden kann. Da hilft auch kein BytesIO, sondern nur eine Bibliothek, die das eben kann. Diese Screenshots sind nichts andere als PIL-Images, es besteht also durchaus die Chance, dass das irgendwer direkt unterstützt.
UniversalBastler
User
Beiträge: 17
Registriert: Samstag 1. August 2020, 12:08

Dann habe ich glaube ich immer noch nicht verstanden, was dein Problem ist. Ein Screenshot ist bei mir immer ein PNG. Wenn du das so abgrenzt zu PNG - was heißt das denn dann? Was ist denn ein screenshot , wenn kein PNG?
Da scheint genau mein Problem zu liegen. Vielleicht denke ich auch zu kompliziert und mache irgendwo einen blöden Fehler.
Mit screenshot1 = pyautogui.screenshot(region=(80,48, 880, 960)) erstelle ich einen screenshot der dann in screenshot1 enthalten ist.
Wenn ich dann aber mit pdf.image(screenshot1, 10 , 40, 200) versuche screenshot1 als Bild (image) auf die PDF Seite zu bringen funktioniert das nicht. Es sollte aber funktionieren wenn screenshot1 ein PNG ist oder?
Erst wenn ich mit screenshot1.save("seiteL.png") den screenshot abspeichere und dann mit seite = "seiteL.png" wieder lade, kann ich mit pdf.image(seite ,10 ,40, 200) den screenshot als Bild auf die PDF Seite bringen.
Sorry wenn ich mich etwas ungelenk ausdrücke. Bei den Fachbegriffen und richtigen Zuordnungen habe ich noch Nachholbedarf.
UniversalBastler
User
Beiträge: 17
Registriert: Samstag 1. August 2020, 12:08

es besteht also durchaus die Chance, dass das irgendwer direkt unterstützt.
Ja, so wird es wohl sein aber den bzw. das Modul zu finden.........
Da lohnt der Aufwand nicht und mit dem Zwischenspeichern komme ich ja zu recht.

Wobei: gibt es keine andere Möglichkeit dem Kind einen Namen zu geben als die zu speichern und wieder zu laden?

:roll: Vielen Dank für eure Bemühungen. :roll:
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Das was du als Screenshot bezeichnest ist ein Python Objekt. Aus dem Modul pyautogui. Das damit ein anderes Modul nicht viel anfangen kann, ist nicht weiter verwunderlich. Dein Auto kann wahrscheinlich auch nix mit dem Motor des Nachbarn anfangen.

Womit wer anders etwas anfangen kann, sind generische Bildformate. Das KANN PNG sein. Oder auch RGB (zb als numpy Array). Man muss also mindestens einen Weg finden, das Objekt in eines dieser Formate zu überführen.

Und dann kommt es noch darauf an, wie die Bibliothek ein genehmes Format annimmt. Es kann sein, das es nur ein Dateipfad ist. Dann kommst du ums Speichern nicht herum. Oder es erlaubt (in Python oft) die Angabe als „file like object“. Also etwas, das sich so verhält, wie eine Datei. Und da kommt dann io.BytesIO zum tragen. Damit „simuliert“ Python eine Datei im Speicher.

Du kannst also versuchen, das Screenshot objekt in ein BytesIO Objekt zu „speichern“ - dann ist es aber nur im Hauptspeicher. Und das dann zu „laden“ mit der PDF Bibliothek.
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Das was du als Screenshot bezeichnest ist ein Python Objekt. Aus dem Modul pyautogui. Das damit ein anderes Modul nicht viel anfangen kann, ist nicht weiter verwunderlich. Dein Auto kann wahrscheinlich auch nix mit dem Motor des Nachbarn anfangen.

Womit wer anders etwas anfangen kann, sind generische Bildformate. Das KANN PNG sein. Oder auch RGB (zb als numpy Array). Man muss also mindestens einen Weg finden, das Objekt in eines dieser Formate zu überführen.

Und dann kommt es noch darauf an, wie die Bibliothek ein genehmes Format annimmt. Es kann sein, das es nur ein Dateipfad ist. Dann kommst du ums Speichern nicht herum. Oder es erlaubt (in Python oft) die Angabe als „file like object“. Also etwas, das sich so verhält, wie eine Datei. Und da kommt dann io.BytesIO zum tragen. Damit „simuliert“ Python eine Datei im Speicher.

Du kannst also versuchen, das Screenshot objekt in ein BytesIO Objekt zu „speichern“ - dann ist es aber nur im Hauptspeicher. Und das dann zu „laden“ mit der PDF Bibliothek.
UniversalBastler
User
Beiträge: 17
Registriert: Samstag 1. August 2020, 12:08

Sorry Leute,
bei stackoverflow habe ich den Hinweis gefunden und wie ich es mir schon gedacht habe ist die Lösung ganz einfach.

Ich weise mit

screenshot1 = pyautogui.screenshot("seiteL.png" ,region=(80,48, 880, 960))

gleich den Namen (seiteL.png) zu und dann mit

pdf.image("seiteL.png" ,10 ,40, 200)

schreibe ich den screenshot auf die PDF Seite.
Ich brauche nichts mehr zwischen zu speichern und alles ist gut.
Nochmals vielen Dank

Nachfolgend für alle die es interessiert der vereinfachte Teilcode

Code: Alles auswählen

import pyautogui
from time import sleep
from fpdf import FPDF 

pdf = FPDF()#PDF wird erstellt

screenshot1 = pyautogui.screenshot("seiteL.png" ,region=(80,48, 880, 960))#screeshot der ersten Seite (linke Hälfte)
sleep(1) #warten bist erledigt

pdf.add_page() #Seite wird dem PDF zugefügt
pdf.image("seiteL.png" ,10 ,40, 200) #screenshot (jetzt seiteL.png) wird auf der PDF Seite positioniert

sleep(1)

pdf.output("PDF-Test3.pdf", "F") #fertiges PDF wird gespeichert
print("Fertig")
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Dann speichert pyautogui halt direkt. Es ist aber immer noch zwischengespeichert. Und das PNG fliegt irgendwo rum.
Sirius3
User
Beiträge: 18261
Registriert: Sonntag 21. Oktober 2012, 17:20

Du speicherst ja trotzdem zwischen, auch wenn das nun die Funktion screenshot direkt für dich erledigt. Aber wenn du meinst, dass das dir Lösung ist, die du gesucht hast, dann ist ja gut. Jetzt muss nur noch der überflüssige Code weg:

Code: Alles auswählen

import pyautogui
from fpdf import FPDF 

pdf = FPDF()

pyautogui.screenshot("seiteL.png" ,region=(80,48, 880, 960))#screeshot der ersten Seite (linke Hälfte)

pdf.add_page()
pdf.image("seiteL.png" ,10 ,40, 200) #screenshot (jetzt seiteL.png) wird auf der PDF Seite positioniert

pdf.output("PDF-Test3.pdf", "F") #fertiges PDF wird gespeichert
print("Fertig")
Antworten