Okay, das mit dem Zwischenspeichern war vielleicht von mir falsch ausgedrückt.
Natürlich muss der screenshot bzw. das Objekt oder Bild irgendwo im Speicher landen sonst könnte man es ja nicht in die PDF Schreiben.
Es ging aber darum, das nicht jedes mal auf die Festplatte zu schreiben.
@Sirius3
vielen Dank für die weitere Bereinigung des Codes. Zumindest das erste sleep(1) hätte ich gedacht, das es gebraucht wird weil angeblich der screenshot durchaus mehrere hundert Millisekunden brauchen kann. Aber es scheint auch so zu gehen
Dass ich die Variable screenshot1 gar nicht brauche erscheint mir (hinterher) auch klar.
Auf jeden Fall wieder was dazu gelernt
screenshot als Bild in PDF speichern
Du *schreibst* das doch jetzt auf die Festplatte. Du instruierst pyautogui das fuer dich zu machen, aber das ist auch der einzige Unterschied. Das wird *immer* noch auf die Platte geschrieben. Und vor allem auch in einen relativen Pfad, das heisst, dass die Datein irgendwo landen - und nicht kontrolliert zB im TEMP-Verzeichnis. Wenigstens dahingehend wuerde ich das Programm noch ueberarbeiten.
-
- User
- Beiträge: 17
- Registriert: Samstag 1. August 2020, 12:08
Ich habe es gerade auch festgestellt.Du *schreibst* das doch jetzt auf die Festplatte.
Aber das macht dann doch pyautogui.screenshot() selbstständig oder?
Na gut, dann soll es halt so sein
Wo das hingeschrieben wird habe ich im Griff, da kann ich einfach den Pfad mit angeben.
Wie schon geschrieben, muss man tief in die Klasse eingreifen, um das zu ändern.
[/quote]
Code: Alles auswählen
import pyautogui
from io import BytesIO
from fpdf import FPDF
class Fpdf(FPDF):
def load_resource(self, reason, file):
if hasattr(file, "read"):
return file
return FPDF.load_resource(self, reason, file)
pdf = Fpdf()
image = BytesIO()
screenshot1 = pyautogui.screenshot(region=(80,48, 880, 960))#screeshot der ersten Seite
screenshot1.save(inage, fornat="png")
image.seek(0)
pdf.add_page() #Seite wird dem PDF zugefügt
pdf.image(image,10, 40, 200, type="png") #screenshot wird auf der PDF Seite positioniert
pdf.output("PDF-Test3.pdf", "F") #fertiges PDF wird gespeichert
print("Fertig")
-
- User
- Beiträge: 17
- Registriert: Samstag 1. August 2020, 12:08
Sorry, soweit bin ich noch nicht.
Trotzdem Danke
Trotzdem Danke
- noisefloor
- User
- Beiträge: 3856
- Registriert: Mittwoch 17. Oktober 2007, 21:40
- Wohnort: WW
- Kontaktdaten:
Hallo,
ReportLab ist mächtiger, weil es (viel) mehr Möglichkeiten hat. Aber deswegen ist es nicht wirklich komplizierter:
Das PDF mit den Screenshot ist dann im Verzeichnis, wo das Skript liegt, als "image.pdf" gespeichert.
Gruß, noisefloor
ReportLab ist mächtiger, weil es (viel) mehr Möglichkeiten hat. Aber deswegen ist es nicht wirklich komplizierter:
Code: Alles auswählen
>>> import pyautogui
>>> from reportlab.platypus import SimpleDocTemplate, Image
>>> from reportlab.lib.pagesizes import A4
>>> from io import BytesIO
>>> image = BytesIO()
>>> screenshot1 = pyautogui.screenshot(region=(80,48, 200, 200))
>>> screenshot1.save(image, format='png')
>>> doc = SimpleDocTemplate("image.pdf", pagesize=A4)
>>> story=[]
>>> story.append(Image(image))
>>> doc.build(story)
Gruß, noisefloor
- __blackjack__
- User
- Beiträge: 13107
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
@noisefloor: Kleine Korrektur: Das PDF ist dann im aktuellen Arbeitsverszeichnis gespeichert. Ob das das gleiche ist in dem das Skript liegt, hängt davon ab wie/von wo man das startet.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
-
- User
- Beiträge: 17
- Registriert: Samstag 1. August 2020, 12:08
Hallo,
Vielen Dank aber ihr bringt mich an meine Grenzen
Also mit BytesIO und reportlap muss ich mich dann doch mal beschäftigen.
Ich bin eigentlich davon ausgegangen, dass mit screenshot1.save(image, format='png') das png Bild auf die Festplatte gespeichert wird, finde es aber nicht.
Oder liegt das an dem BytesIO ? Gut, muss ich mich erst einarbeiten.
Das reportlab muss ich auch tiefer eintauchen, das Bild (Screenshot eines halben Bildschirm's) kann sicher auch hier so skaliert werden, dass es auf eine A4 Seite passt.
Vielen Dank aber ihr bringt mich an meine Grenzen
Also mit BytesIO und reportlap muss ich mich dann doch mal beschäftigen.
Ich bin eigentlich davon ausgegangen, dass mit screenshot1.save(image, format='png') das png Bild auf die Festplatte gespeichert wird, finde es aber nicht.
Oder liegt das an dem BytesIO ? Gut, muss ich mich erst einarbeiten.
Das reportlab muss ich auch tiefer eintauchen, das Bild (Screenshot eines halben Bildschirm's) kann sicher auch hier so skaliert werden, dass es auf eine A4 Seite passt.
- noisefloor
- User
- Beiträge: 3856
- Registriert: Mittwoch 17. Oktober 2007, 21:40
- Wohnort: WW
- Kontaktdaten:
Hallo,
Gruß, noisefloor
Tut's auch. Das Bild sollte da liegen, wo das aktuelle Arbeitsverzeichnis des Skripts ist.Ich bin eigentlich davon ausgegangen, dass mit screenshot1.save(image, format='png') das png Bild auf die Festplatte gespeichert wird, finde es aber nicht.
Nein. Mit BytesIO erzeugst du ein "file-like object", also ein Objekt, was sich wie eine Datei verhält (aber nicht unbedingt eine ist). Mit BytesIO sparst du dir den Zwischenschritt des Speicherns auf ein Laufwerk, das Bild bzw. die "Datei" wird im Speicher gehalten.Oder liegt das an dem BytesIO ? Gut, muss ich mich erst einarbeiten.
Ja, aber nicht über ReportLab. Die Platypus.Image Klasse kennt keine Größenangaben. Das musst du vorher machen. PyAutoGUI.screenshot liefert dir ja ein PIL Objekt, das hat Methoden, um das Bild zu skalieren:Das reportlab muss ich auch tiefer eintauchen, das Bild (Screenshot eines halben Bildschirm's) kann sicher auch hier so skaliert werden, dass es auf eine A4 Seite passt.
Code: Alles auswählen
>> from pyautogui import screenshot
>>> image = screenshot()
>>> image
<PIL.PngImagePlugin.PngImageFile image mode=RGB size=1366x768 at 0x7F6286F1C610>
>>> image.size
(1366, 768)
>>> image = image.resize((800, 450))
>>> image.size
(800, 450)
@UniversalBastler: image ist ein BytesIO-Objekt, `save` speichert also nur was im Speicher und nicht auf Festplatte. Das ist doch das, was Du möchtest.
@noisefloor: resize verändert doch nur die Pixelanzahl und hat erstmal nichts damit zu tun, wie groß das Bild dann auf der PDF-Seite dargestellt wird.
@noisefloor: resize verändert doch nur die Pixelanzahl und hat erstmal nichts damit zu tun, wie groß das Bild dann auf der PDF-Seite dargestellt wird.
- noisefloor
- User
- Beiträge: 3856
- Registriert: Mittwoch 17. Oktober 2007, 21:40
- Wohnort: WW
- Kontaktdaten:
Hallo,
was ich oben bzgl. des Skalierens in `platypus.Image`gesagt habe ist auch nicht korrekt. Die Objekt-Klasse vom Image kennt Größenangaben:
skaliert das Bild direkt. Wobei man auch direkt auf eine bestimmte Größe in z.B. cm skalieren kann:
würde das Bild auf 5x3cm im PDF skalieren.
Gruß, noisefloor
was ich oben bzgl. des Skalierens in `platypus.Image`gesagt habe ist auch nicht korrekt. Die Objekt-Klasse vom Image kennt Größenangaben:
Code: Alles auswählen
>>> story.append(Image(image, 800, 600))
Code: Alles auswählen
...
from reportlab.lib.units import cm
from reportlab.platypus import Image
...
story.append(Image(image, 5*cm, 3*cm))
...
Gruß, noisefloor
-
- User
- Beiträge: 17
- Registriert: Samstag 1. August 2020, 12:08
Danke, das hilft mir ein ganzes Stück weiter.skaliert das Bild direkt. Wobei man auch direkt auf eine bestimmte Größe in z.B. cm skalieren kann:
In Verbindung mit bytesIO habe ich mein Programm jetzt fast komplett umgeschrieben und es funktioniert bis hierhin.
Jetzt muss ich nur noch beide Bildschirmhälften nacheinander scannen, und das in eine Schleife einbauen damit es mehrere Bildschirme/Seiten nacheinander bearbeitet.
Dazu muss ich aber erst in reportlab etwas tiefer eintauchen. Ich habe mich schon mal umgeschaut, aber nicht wirklich viel gefunden was ich mit meinen nur rudimentären Englischkenntnissen problemlos erfassen könnte. Hat jemand eine Quelle, ein Buch oder eine Webseite wo reportlab gut und möglichst in deutsch beschrieben ist? fpdf habe ich zum Beispiel im Buch "Routineaufgaben mit Python automatisieren" kennengelernt und daher auch anfangs eingesetzt.
P.S. wiki.ubuntuusers.de/ReportLab/ kenne ich natürlich.
- noisefloor
- User
- Beiträge: 3856
- Registriert: Mittwoch 17. Oktober 2007, 21:40
- Wohnort: WW
- Kontaktdaten:
Hallo,
also ich kenne kein Buch. Die Doku von ReportLab ist sehr umfangreich und es gibt im Netz sehr sehr viele Beispiele und Codeschnipsel zu Reportlab.
Platypus, was ja die "high level" API zum Bauen von PDFs mit ReporLab ist, nutzt man normalerweise so, dass man eine Liste (in vielen Beispielen "story" benannt) hat, in die man alle Elemente, die das PDF haben soll, packt. "Elemente" sind hier die Klassen, die Platypus so kennt, also Paragraphen, Bilder, etc. Die Elemente sind im Jargon von Platypus als "Flowables" bezeichnet.
Ein 2-seitiges PDF baust du so:
Den `PageBreak`kannst / solltest du sicherheitshalber einbauen, damit garantiert eine da ist. enn Das 1. Bild so groß ist, dass das 2. Bild nicht mehr auf die 1. Seite des PDFs passt, dann wird natürlich automatisch ein Seitenumbruch eingebaut.
Den obigen, linearen Code solltest du dann natürlich sinnvoll in Funktionen packen, wenn du Screenshots von mehreren Bildschirmen brauchst.
Gruß, noisefloor
also ich kenne kein Buch. Die Doku von ReportLab ist sehr umfangreich und es gibt im Netz sehr sehr viele Beispiele und Codeschnipsel zu Reportlab.
Platypus, was ja die "high level" API zum Bauen von PDFs mit ReporLab ist, nutzt man normalerweise so, dass man eine Liste (in vielen Beispielen "story" benannt) hat, in die man alle Elemente, die das PDF haben soll, packt. "Elemente" sind hier die Klassen, die Platypus so kennt, also Paragraphen, Bilder, etc. Die Elemente sind im Jargon von Platypus als "Flowables" bezeichnet.
Ein 2-seitiges PDF baust du so:
Code: Alles auswählen
>>> import pyautogui
>>> from reportlab.platypus import SimpleDocTemplate, Image, PageBreak
>>> from reportlab.lib.pagesizes import A4
>>> from io import BytesIO
>>> image_left = BytesIO()
>>> image_right = BytesIO()
>>> screenshot_left = pyautogui.screenshot(region=(80,48, 200, 200))
>>> screenshot_right = pyautogui.screenshot(region=(300,300, 200, 200))
>>> screenshot_left.save(image_left, format='png')
>>> screenshot_right.save(image_rigth, format='png')
>>> doc = SimpleDocTemplate("image.pdf", pagesize=A4)
>>> story=[]
>>> story.append(Image(image_left, 150, 150))
>>> story.append(PageBreak())
>>> story.append(Image(image_right, 150, 150))
>>> doc.build(story)
Den obigen, linearen Code solltest du dann natürlich sinnvoll in Funktionen packen, wenn du Screenshots von mehreren Bildschirmen brauchst.
Gruß, noisefloor
@noisefloor: statt Code zu kopieren und nur leicht zu ändern, schreibt man sich eine Funktion. Bei einer fixen Anzahl an Elementen für eine Liste schreibt man diese gleich in die eckigen Klammern:
Code: Alles auswählen
import pyautogui
from reportlab.platypus import SimpleDocTemplate, Image, PageBreak
from reportlab.lib.pagesizes import A4
from io import BytesIO
def create_screenshot(region):
screenshot = pyautogui.screenshot(region=region)
image = BytesIO()
screenshot.save(image, format='png')
return Image(image, 150, 150)
story = [
create_screenshot(region=(80,48, 200, 200)),
PageBreak(),
create_screenshot(region=(300,300, 200, 200)),
]
doc = SimpleDocTemplate("image.pdf", pagesize=A4)
doc.build(story)
- noisefloor
- User
- Beiträge: 3856
- Registriert: Mittwoch 17. Oktober 2007, 21:40
- Wohnort: WW
- Kontaktdaten:
Hallo,
@Sirius3: genau das habe ich ja auch im letzten Satz im vorherigen Post geschrieben... Basierend auf dem, was der TE geschrieben hat, kann es durchaus auch Sinn machen, das Bauen des PDFs in eine Funktion zu packen.
Gruß, noisefloor
@Sirius3: genau das habe ich ja auch im letzten Satz im vorherigen Post geschrieben... Basierend auf dem, was der TE geschrieben hat, kann es durchaus auch Sinn machen, das Bauen des PDFs in eine Funktion zu packen.
Gruß, noisefloor
- noisefloor
- User
- Beiträge: 3856
- Registriert: Mittwoch 17. Oktober 2007, 21:40
- Wohnort: WW
- Kontaktdaten:
Hallo,
passend zum Thema: der aktuelle Real Python Podcast behandelt Python, PDFs und ReportLab (https://realpython.com/podcasts/rpp/20/). Und es gibt doch ein (englischsprachiges) ReportLab Buch (https://leanpub.com/reportlab). Habe mal virtuell die ersten 54 Seiten durchgeblättert, die man kostenlos als Demo anschauen kann. Das sieht eher so aus, als wäre das ein Re-Write der ReportLab Doku, womit das Buch.. na ja nur semi-sinnvoll wäre. Das Kapitel zu Platypus kann man in der kostenlosen Ansicht leider nicht anschauen.
Gruß, noisefloor
passend zum Thema: der aktuelle Real Python Podcast behandelt Python, PDFs und ReportLab (https://realpython.com/podcasts/rpp/20/). Und es gibt doch ein (englischsprachiges) ReportLab Buch (https://leanpub.com/reportlab). Habe mal virtuell die ersten 54 Seiten durchgeblättert, die man kostenlos als Demo anschauen kann. Das sieht eher so aus, als wäre das ein Re-Write der ReportLab Doku, womit das Buch.. na ja nur semi-sinnvoll wäre. Das Kapitel zu Platypus kann man in der kostenlosen Ansicht leider nicht anschauen.
Gruß, noisefloor