Seitennummern in pdf einfügen
also ich gebe auf, das ist mir zu hoch So siehts jetzt aus, aber es läuft nicht, weil watermark für merge() nicht vorhanden ist...und das ist bestimmt nicht der letzte Bug
http://paste.pocoo.org/show/5IuzHLRXltdZXhLrVPZV/
http://paste.pocoo.org/show/5IuzHLRXltdZXhLrVPZV/
jetzt habe ich versucht, auch dieses problem zu vertagen und mich auf das multiprocessing zu konzentrieren,
ich bin also noch einen Schritt zurück gegangen, aber jetzt ist irgendwie eine schleife entstanden, denn es werden immer mehr temp- Ordner angelegt in denen sich jeweils eine temp.pdf befindet .......
ich bin also noch einen Schritt zurück gegangen, aber jetzt ist irgendwie eine schleife entstanden, denn es werden immer mehr temp- Ordner angelegt in denen sich jeweils eine temp.pdf befindet .......
Code: Alles auswählen
# -*- coding: iso-8859-15 -*-
from __future__ import division,unicode_literals
from pyPdf import PdfFileWriter, PdfFileReader
from tempfile import mkdtemp
from shutil import rmtree
from reportlab.pdfgen import canvas
from reportlab.lib.units import cm
from reportlab.lib.colors import black
from tempfile import NamedTemporaryFile
from reportlab.lib.pagesizes import A3, A4, landscape
from thread import start_new_thread
from multiprocessing import Pool
import os
tempdir=mkdtemp(suffix='TemppP')
#def output():
def merge(pagenum):
page=input1.getPage(pagenum)
page.mergePage(watermark.getPage(pagenum))
output.addPage(page)
#def output(input1,pages):
#global watermark
output = PdfFileWriter()
input1 = PdfFileReader(file("test_lang.pdf", "rb"))
pages=input1.getNumPages()
currentSeitenformat=0
if currentSeitenformat==0: #A4-hoch
rx=19*cm
ry=28.3*cm
rdx=4*cm
rdy=4*cm
x=19.3*cm
y=28.6*cm
c = canvas.Canvas(tempdir+"\\temp.pdf",pagesize=A4)
rot=0
c.setFont("Helvetica",11)
page=54
pre="N"
post="c"
for pagenum in range(pages):
c.setFillGray(0.75)
# draw a rectangle
c.rotate(rot)
c.rect(rx,ry,rdx,rdy, stroke=0, fill=1)
c.setStrokeColor(black)
c.setFillColor(black)
c.drawString(x,y,(pre+str(page+pagenum)+post))
c.showPage()
c.save()
with open (tempdir+"\\temp.pdf", "rb") as (tmp_file):
watermark = PdfFileReader(tmp_file)
for pagenum in range(pages):
pool = Pool() #?????
pool.map(merge,range(pages))
temp_file = NamedTemporaryFile(suffix = '.pdf', prefix = 'temp',delete=False,dir =tempdir)
output.write(temp_file)
os.startfile(temp_file.name)
temp_file.close()
#if __name__ == "__main__":
# output()
@mathi: `Pool.map()` startet n Prozesse (n = Anzahl der Prozessoren/Kerne) mit der angegeben Funktion und wendet diese auf alle Argumente in dem "iterable" an. Und Du baust da jetzt eine Schleife drumherum, die soviele von diesen Pools erzeugt wie Seiten da sind. Wieviele Prozesse hättest Du denn da jetzt erwartet und warum? Ich habe so langsam das Gefühl Du probierst nur wild herum und hoffst, dass da irgendwann schon die richtige Kombination von Schleifen und Aufrufen bei herauskommt. So funktioniert Programmieren nicht wirklich.
@BlackJack
ich komme mit der doku nicht wirklich zurecht, Beispiele finden sich kaum (ich habe keine für mich verwertbaren gefunden), so versuche ich halt so gut es geht. Natürlich hast Du recht, aber das sagt sich leicht wenn man weiß wie es geht...
ich komme mit der doku nicht wirklich zurecht, Beispiele finden sich kaum (ich habe keine für mich verwertbaren gefunden), so versuche ich halt so gut es geht. Natürlich hast Du recht, aber das sagt sich leicht wenn man weiß wie es geht...
Du brauchst nur einen Pool. Also 59 löschen, 60 und 61 ausrücken.
Da die zeitliche Reihenfolge der Aufrufe von 22 nicht unbedingt der Reihenfolge der Seiten entsprechen muss, sollte merge lieber page zurückliefern. Dann kannst Du das PDF-File aus der von pool.map erzeugten Liste generieren.
Und räume Deinen Code unbedingt etwas auf. Ich bin zwar kein PEP-8-Fanatiker, aber Deinen Code zu lesen, ist doch sehr anstrengend.
MfG
HWK
Da die zeitliche Reihenfolge der Aufrufe von 22 nicht unbedingt der Reihenfolge der Seiten entsprechen muss, sollte merge lieber page zurückliefern. Dann kannst Du das PDF-File aus der von pool.map erzeugten Liste generieren.
Und räume Deinen Code unbedingt etwas auf. Ich bin zwar kein PEP-8-Fanatiker, aber Deinen Code zu lesen, ist doch sehr anstrengend.
MfG
HWK
ich habe den code mal ein bissel gestrafft, und soweit scheint das zusammenführen der .pdf Dateien auch zu funktionieren, leider erhalte ich eine korrupte Ergebnisdatei, woran kann das liegen??
(mir ist klar, dass es nicht gut ist input1 2-mal zu erzeugen unter main() und unter merge(), aber mir geht es erst einmal darum dass das programm funktioniert, danach möchte ich mich erst um solche Dinge kümmern)
(Ich habe jetzt das generieren der .pdf ausgespart, wer es testen möchte brauch nur eine .pdf in "test_lang.pdf" umzubenennen und die gleiche oder eine mit der selben Anzahl an Seiten als "temp.pdf" zu bezeichnen..)
(mir ist klar, dass es nicht gut ist input1 2-mal zu erzeugen unter main() und unter merge(), aber mir geht es erst einmal darum dass das programm funktioniert, danach möchte ich mich erst um solche Dinge kümmern)
Code: Alles auswählen
# -*- coding: iso-8859-15 -*-
from pyPdf import PdfFileWriter, PdfFileReader
from tempfile import mkdtemp
from reportlab.pdfgen import canvas
from tempfile import NamedTemporaryFile
import os, multiprocessing
tempdir=mkdtemp(suffix='TemppP')
output = PdfFileWriter()
pagelist=[] # Liste zum zwischenparken der pages in merge()
def main():
input1 = PdfFileReader(file("test_lang.pdf", "rb"))
pages=input1.getNumPages()
pool = multiprocessing.Pool()
pool.map(merge,range(pages))
for page in pagelist:
output.addPage(page)
temp_file = NamedTemporaryFile(suffix = '.pdf', prefix = 'temp',delete=False,dir =tempdir)
output.write(temp_file)
os.startfile(temp_file.name)
temp_file.close()
def merge(pagenum):
input1 = PdfFileReader(file("test_lang.pdf", "rb")) #Orginaldatei
#with open ("temp.pdf", "rb") as (tmp_file):
watermark = PdfFileReader(file("temp.pdf", "rb")) # temp-Datei mit den Seitennummern muß die gleiche Seitenanzahl haben
page=input1.getPage(pagenum)
page.mergePage(watermark.getPage(pagenum))
pagelist.append(page)
if __name__ == "__main__":
main()
Warum verwendest Du in merge nicht wie vorgeschlagen
? pool.map liefert dann eine Liste der Seiten in der richtigen Reihenfolge. So ist die Reihenfolge der neuen Seiten nicht zwingend dieselbe wie die der alten.
MfG
HWK
Code: Alles auswählen
return page
MfG
HWK
werde ich machen, aber wie heißt denn die Liste, die return zurückgibt? Ich muß doch die einzelnen pages z.B. mit einer for-Schleife zum output hinzufügen, möglichst in der richtigen reihenfolge..
Vielen Dank für die geduld, die Ihr mit mir habt
Vielen Dank für die geduld, die Ihr mit mir habt
pool.map liefert die Liste zurück! Ist doch aus der Doku echt offensichtlich, du musst doch eigentlich nur diese EINE Zeile nachvollziehen können, dann ist doch komplett klar, was die map Funktion macht und zurückgibt:mathi hat geschrieben:werde ich machen, aber wie heißt denn die Liste, die return zurückgibt? Ich muß doch die einzelnen pages z.B. mit einer for-Schleife zum output hinzufügen, möglichst in der richtigen reihenfolge..
Vielen Dank für die geduld, die Ihr mit mir habt
Code: Alles auswählen
print pool.map(f, range(10)) # prints "[0, 1, 4,..., 81]"
wenn das so einfach wäre, hätte ich nicht gefragt, denn mit
erhalte ich folgenden Fehler:
dieser tritt in org. Programm also ohne multiprocessing nicht auf. Das heißt doch, dass
entweder beim Erstellen der Liste in map() was schief läuft oder das ich nicht die richtigen Objekte an output übergebe, oder??
bedeutet doch, das der Startwert nicht stimmt??
Code: Alles auswählen
# -*- coding: iso-8859-15 -*-
from pyPdf import PdfFileWriter, PdfFileReader
from tempfile import mkdtemp
from reportlab.pdfgen import canvas
from tempfile import NamedTemporaryFile
import os, multiprocessing
#tempdir=mkdtemp(suffix='TemppP')
def main():
output = PdfFileWriter()
input1 = PdfFileReader(file("test_lang.pdf", "rb"))
pages=input1.getNumPages()
pool = multiprocessing.Pool()
pagelist=pool.map(merge,range(pages))
for page in pagelist:
output.addPage(page)
temp_file = NamedTemporaryFile(suffix = '.pdf', prefix = 'temp',delete=False)
output.write(temp_file)
os.startfile(temp_file.name)
temp_file.close()
def merge(pagenum):
input1 = PdfFileReader(file("test_lang.pdf", "rb")) #Orginaldatei
#with open ("temp.pdf", "rb") as (tmp_file):
watermark = PdfFileReader(file("temp.pdf", "rb"))
page=input1.getPage(pagenum)
page.mergePage(watermark.getPage(pagenum))
return page
if __name__ == "__main__":
main()
Code: Alles auswählen
Traceback (most recent call last):
File "D:\Python\Code\wxPython\workspace\pdfPage\src\pdfPageCMD1.py", line 35, in <module>
main()
File "D:\Python\Code\wxPython\workspace\pdfPage\src\pdfPageCMD1.py", line 22, in main
output.write(temp_file)
File "C:\Python26\lib\site-packages\pyPdf\pdf.py", line 237, in write
self._sweepIndirectReferences(externalReferenceMap, self._root)
File "C:\Python26\lib\site-packages\pyPdf\pdf.py", line 312, in _sweepIndirectReferences
self._sweepIndirectReferences(externMap, realdata)
File "C:\Python26\lib\site-packages\pyPdf\pdf.py", line 288, in _sweepIndirectReferences
value = self._sweepIndirectReferences(externMap, value)
File "C:\Python26\lib\site-packages\pyPdf\pdf.py", line 312, in _sweepIndirectReferences
self._sweepIndirectReferences(externMap, realdata)
File "C:\Python26\lib\site-packages\pyPdf\pdf.py", line 288, in _sweepIndirectReferences
value = self._sweepIndirectReferences(externMap, value)
File "C:\Python26\lib\site-packages\pyPdf\pdf.py", line 297, in _sweepIndirectReferences
value = self._sweepIndirectReferences(externMap, data[i])
File "C:\Python26\lib\site-packages\pyPdf\pdf.py", line 312, in _sweepIndirectReferences
self._sweepIndirectReferences(externMap, realdata)
File "C:\Python26\lib\site-packages\pyPdf\pdf.py", line 288, in _sweepIndirectReferences
value = self._sweepIndirectReferences(externMap, value)
File "C:\Python26\lib\site-packages\pyPdf\pdf.py", line 288, in _sweepIndirectReferences
value = self._sweepIndirectReferences(externMap, value)
File "C:\Python26\lib\site-packages\pyPdf\pdf.py", line 288, in _sweepIndirectReferences
value = self._sweepIndirectReferences(externMap, value)
File "C:\Python26\lib\site-packages\pyPdf\pdf.py", line 318, in _sweepIndirectReferences
newobj = data.pdf.getObject(data)
File "C:\Python26\lib\site-packages\pyPdf\pdf.py", line 615, in getObject
self.stream.seek(start, 0)
ValueError: I/O operation on closed file
entweder beim Erstellen der Liste in map() was schief läuft oder das ich nicht die richtigen Objekte an output übergebe, oder??
Code: Alles auswählen
self.stream.seek(start, 0)
mal abgesehen davon, dass es mit functools.partail und pool.map() generell probleme zu geben scheint (http://mail.python.org/pipermail/python ... 86039.html) habe ich mal probiert das einzubauen(mit dem Umweg vgl. mailinglist):
ich erhalte die Fehlermeldung:
habe ich partial falsch verwendet?? So wie ich das verstehe, übergebe ich genau die Werte (von links nach rechts) die ich in der Funktion merge() brauche und nicht in pool.map übergeben kann ???
Code: Alles auswählen
# -*- coding: iso-8859-15 -*-
from pyPdf import PdfFileWriter, PdfFileReader
from tempfile import mkdtemp
from reportlab.pdfgen import canvas
from tempfile import NamedTemporaryFile
import os, multiprocessing,copy_reg, functools
#Beginn: making functools.partial picklable
def _reconstruct_partial(f, args, kwds):
return functools.partial(f, *args, **(kwds or {}))
def _reduce_partial(p):
return _reconstruct_partial, (p.func, p.args, p.keywords)
copy_reg.pickle(functools.partial, _reduce_partial)
#Ende: making functools.partial picklable
def main():
output = PdfFileWriter()
input1 = PdfFileReader(file("test_lang.pdf", "rb"))
watermark = PdfFileReader(file("temp.pdf", "rb"))
pages=input1.getNumPages()
merge2=functools.partial(merge,input1=input1,watermark=watermark) #<-- functools.partial
#for pagenum in range(pages): # so funktioniert es
# output.addPage(merge2(pagenum)) # so funktioniert es
pool = multiprocessing.Pool() # so geht's nicht
for page in pool.map(merge2,range(pages)): # so geht's nicht
output.addPage(page) # so geht's nicht
temp_file = NamedTemporaryFile(suffix = '.pdf', prefix = 'temp',delete=False)
output.write(temp_file)
os.startfile(temp_file.name)
temp_file.close()
def merge(pagenum,input1,watermark):
page=input1.getPage(pagenum)
page.mergePage(watermark.getPage(pagenum))
return page
if __name__ == "__main__":
main()
Code: Alles auswählen
Traceback (most recent call last):
File "D:\Python\Code\wxPython\workspace\pdfPage\src\pdfPageCMD1.py", line 45, in <module>
main()
File "D:\Python\Code\wxPython\workspace\pdfPage\src\pdfPageCMD1.py", line 30, in main
pagelist=pool.map(merge2,range(pages))
File "C:\Python26\lib\multiprocessing\pool.py", line 148, in map
return self.map_async(func, iterable, chunksize).get()
File "C:\Python26\lib\multiprocessing\pool.py", line 422, in get
raise self._value
ValueError: I/O operation on closed file
Zuletzt geändert von mathi am Montag 7. Dezember 2009, 14:21, insgesamt 1-mal geändert.
Offensichtlich werden die Dateien zwischenzeitlich geschlossen. Lies doch die Seiten erst alle in eine Queue ein (vor pool.map) und hole Dir dann in merge die Seiten aus der Queue. Du musst dann natürlich auch die Seitennummer in der Queue speichern. Das Erstellen der Wassermarke könntest Du dann auch in merge erledigen.
MfG
HWK
MfG
HWK
es ist zum Mäusemelken:
dieses pool.map bringt mich noch ins grab ,
zumindest könnte ich mit Queue die probleme mit functools.partial umgehen
ich hab testweise mal 2 Queue erstellt. Ohne multiprocessing funktioniert es wie es soll, aber mit pool.map startet die Iteration schon gar nicht
Code: Alles auswählen
# -*- coding: iso-8859-15 -*-
from pyPdf import PdfFileWriter, PdfFileReader
from tempfile import NamedTemporaryFile
from Queue import Queue
import os, multiprocessing
q_seiten = Queue()
q_zahlen=Queue()
def main():
output = PdfFileWriter()
input1 = PdfFileReader(file("test_lang.pdf", "rb"))
watermark = PdfFileReader(file("temp.pdf", "rb"))
pages=input1.getNumPages()
for pagenum in range(pages):
q_seiten.put(input1.getPage(pagenum))
q_zahlen.put(watermark.getPage(pagenum))
#for pagenum in range(pages): # so funktioniert es
# output.addPage(merge(pagenum)) # so funktioniert es
pool = multiprocessing.Pool() # so geht's nicht
for page in pool.map(merge,range(pages)): # so geht's nicht
output.addPage(page) # so geht's nicht
temp_file = NamedTemporaryFile(suffix = '.pdf', prefix = 'temp',delete=False)
output.write(temp_file)
os.startfile(temp_file.name)
temp_file.close()
def merge(pagenum):
#while True:
page=q_seiten.get()
page.mergePage(q_zahlen.get())
return page
q_seiten.task_done()
q_zahlen.task_done()
#q_zahlen.join()
if __name__ == "__main__":
main()
zumindest könnte ich mit Queue die probleme mit functools.partial umgehen
ich hab testweise mal 2 Queue erstellt. Ohne multiprocessing funktioniert es wie es soll, aber mit pool.map startet die Iteration schon gar nicht
Da ich das Gefühl hatte, dass es it pool.map nix wird, habe ich mal versucht mit Process() weiterzukommen:
Ich haber erstmal nur einen Prozess, um zu sehen ob es funktioniert...die Fehlermeldung lautet:
da ich aber sämtliche Seiten in je eine Queue gepackt habe, kann
Code: Alles auswählen
# -*- coding: iso-8859-15 -*-
from pyPdf import PdfFileWriter, PdfFileReader
from tempfile import NamedTemporaryFile
from multiprocessing import Process, Queue
import os
def merge1(q1s,q1z):
while True:
page=q1s.get()
page.mergePage(q1z.get())
q1a.put(page)
q1s.task_done()
q1z.task_done()
if __name__ == '__main__':
output = PdfFileWriter()
input1 = PdfFileReader(file("test_lang.pdf", "rb"))
watermark = PdfFileReader(file("temp.pdf", "rb"))
pages=input1.getNumPages()
q1s=Queue() #Seiten=input1
q1z=Queue() #Seitenzahlen = watermark
q1a=Queue() #Output
for i in xrange(pages):
q1s.put(input1.getPage(i))
q1z.put(watermark.getPage(i))
p1 = Process(target=merge1, args=(q1s,q1z))
p1.start()
p1.join()
while True:
page=q1a.get()
output.addPage(page)
temp_file = NamedTemporaryFile(suffix = '.pdf', prefix = 'temp',delete=False)
output.write(temp_file)
os.startfile(temp_file.name)
temp_file.close()
Code: Alles auswählen
Process Process-1:
Traceback (most recent call last):
File "C:\Python26\lib\multiprocessing\process.py", line 232, in _bootstrap
self.run()
File "C:\Python26\lib\multiprocessing\process.py", line 88, in run
self._target(*self._args, **self._kwargs)
File "D:\Python\Code\wxPython\workspace\pdfPage\src\pdfPageCMD5a.py", line 12, in merge1
page.mergePage(q1z.get())
File "C:\Python26\lib\site-packages\pyPdf\pdf.py", line 1095, in mergePage
self._mergePage(page2)
File "C:\Python26\lib\site-packages\pyPdf\pdf.py", line 1122, in _mergePage
new, newrename = PageObject._mergeResources(originalResources, page2Resources, res)
File "C:\Python26\lib\site-packages\pyPdf\pdf.py", line 1030, in _mergeResources
page2Res = res2.get(resource, DictionaryObject()).getObject()
File "C:\Python26\lib\site-packages\pyPdf\generic.py", line 165, in getObject
return self.pdf.getObject(self).getObject()
File "C:\Python26\lib\site-packages\pyPdf\pdf.py", line 615, in getObject
self.stream.seek(start, 0)
ValueError: I/O operation on closed file
doch nicht stimmen...HWK hat geschrieben:Offensichtlich werden die Dateien zwischenzeitlich geschlossen.
page enthält wohl nicht den Seiteninhalt der pdf-Datei, sondern nur eine Referenz darauf. Der Inhalt muss also erst wieder aus der Datei ausgelesen werden, die aber offensichtlich schon wieder geschlossen wurde. Auch zum Schreiben der Ausgabe muss wohl die Eingabedatei geöffnet sein. Versuch doch mal statt
um den GC am Schließen der datei zu hindern. Damit kannst Du ja mal Deine verscheidenen Varianten testen.
MfG
HWK
Code: Alles auswählen
input1 = PdfFileReader(file("test_lang.pdf", "rb"))
Code: Alles auswählen
with open('test_lang.pdf', 'rb') as infile:
input1 = PdfFileReader(infile)
MfG
HWK
@HWK.
vielen Dank für Deine Geduld, ich bin froh, dass ich Hilfe bekomme
zusammengefasst kann man sagen, es ändert sich nichts
Hier mal die vielversprechendste Version:http://paste.pocoo.org/show/XcyNU3ej5Bk8zEOVwqPb/
es werden 4 python.exe im Tastmanager angezeigt, es wird aber nichts gerechnet...
in der Version mit Process() http://paste.pocoo.org/show/ruDIdmowrkJixVQqy1B0/
bleibt die Fehlermeldung.
Kann es sein, dass es an pypdf liegt??
vielen Dank für Deine Geduld, ich bin froh, dass ich Hilfe bekomme
zusammengefasst kann man sagen, es ändert sich nichts
Hier mal die vielversprechendste Version:http://paste.pocoo.org/show/XcyNU3ej5Bk8zEOVwqPb/
es werden 4 python.exe im Tastmanager angezeigt, es wird aber nichts gerechnet...
in der Version mit Process() http://paste.pocoo.org/show/ruDIdmowrkJixVQqy1B0/
bleibt die Fehlermeldung.
Kann es sein, dass es an pypdf liegt??
Das wird zwar das Problem nicht lösen, aber neue vermeiden:
Du solltest nur eine Queue verwenden, in der Du Tuple aus der Seitennummer, der Originalseite und der "Partnerseite" speicherst, damit Du sicher sein kannst die richtigen Seiten zu verknüpfen und deren Seitennummer kennst. merge sollte ein Tuple aus Seitennummer und der fertigen Seiten zurückliefern. Zum Schluss solltest Du die Seiten in der Reihenfolge ihrer Seitennummer ausgeben.
Um den Fehler einzugrenzen, solltest Du ein paar informative Prints einbauen, z.B. in merge pagenum und page ausgeben lassen etc. Dann kann man weiter sehen.
Ich möchte wohl verständlicherweise meinen Rechner nicht mit Modulen "zuzumüllen", die ich ansonsten nicht brauche, um Deine Scripts zu testen.
MfG
HWK
Du solltest nur eine Queue verwenden, in der Du Tuple aus der Seitennummer, der Originalseite und der "Partnerseite" speicherst, damit Du sicher sein kannst die richtigen Seiten zu verknüpfen und deren Seitennummer kennst. merge sollte ein Tuple aus Seitennummer und der fertigen Seiten zurückliefern. Zum Schluss solltest Du die Seiten in der Reihenfolge ihrer Seitennummer ausgeben.
Um den Fehler einzugrenzen, solltest Du ein paar informative Prints einbauen, z.B. in merge pagenum und page ausgeben lassen etc. Dann kann man weiter sehen.
Ich möchte wohl verständlicherweise meinen Rechner nicht mit Modulen "zuzumüllen", die ich ansonsten nicht brauche, um Deine Scripts zu testen.
MfG
HWK
so, ich habs mal so gemacht, wie vorgeschlagen (außer der Ergebnistupelausgabe)
hier mal dasergebnis: http://paste.pocoo.org/show/jE9BOITC2OJWdtqX2cRk/
als singleprocess funktioniert es (natürlich),
aber es hängt beim start der pool.map, denn hier die Ausgabe:
es wird die Zeile
gar nicht erst ausgeführt, d.h. merge nicht ein einziges mal aufgerufen...
übrigens das auskommentierte bringt einen timeout
hier mal dasergebnis: http://paste.pocoo.org/show/jE9BOITC2OJWdtqX2cRk/
als singleprocess funktioniert es (natürlich),
aber es hängt beim start der pool.map, denn hier die Ausgabe:
Code: Alles auswählen
test1
test1.1
Code: Alles auswählen
maplist= pool.map(merge,xrange(pages))
übrigens das auskommentierte
Code: Alles auswählen
print result.get(timeout=10)