Seite 1 von 3
Wand TypeError
Verfasst: Freitag 15. März 2019, 18:54
von Felix92
Huhu und zwar habe ich ein Problem, ich möchte einen neuen Ordner erstellen (was auch klappt) und eine pdf-Datei in Bilder splitten (pdf-Datei hat Rechte chmod -v 777 kickoff18.pdf) allerdings bekomme ich ständig eine Fehlermeldung:
Code: Alles auswählen
Traceback (most recent call last):
File "main.py", line 5, in <module>
presentation.convert("/home/felix/Schreibtisch/PythonTest/", "kickoff18.pdf", "/home/felix/Schreibtisch/PythonTest/", "neuerOrdner")
File "/home/felix/Schreibtisch/PythonTest/model/presentation.py", line 16, in convert
pdf = wa(filename = path + filename, resolution=300)
File "/usr/lib/python2.7/dist-packages/wand/image.py", line 2744, in __init__
self.read(filename=filename, resolution=resolution)
File "/usr/lib/python2.7/dist-packages/wand/image.py", line 2822, in read
self.raise_exception()
File "/usr/lib/python2.7/dist-packages/wand/resource.py", line 222, in raise_exception
raise e
wand.exceptions.PolicyError: not authorized `/home/felix/Schreibtisch/PythonTest/kickoff18.pdf' @ error/constitute.c/ReadImage/412
Exception TypeError: TypeError("object of type 'NoneType' has no len()",) in <bound method Image.__del__ of <wand.image.Image: (empty)>> ignored
presentation:
Code: Alles auswählen
from wand.image import Image as wa
import os, os.path
class Presentation:
"""Class that divides a PDF into individual images and converts them to jpg"""
def __init__(self):
"""Constructor of the class"""
pass
def convert(self, path, filename, folder_path, folder_name):
"""a method that takes a path and a PDF file, converts them to JPG, and then saves the individual images"""
folder = folder_path + folder_name
os.makedirs(folder)
pdf = wa(filename = path + filename, resolution=300)
pdf_images = pdf.convert("jpeg")
print("Bis hier")
os.chdir(folder)
page_number = 1
for img in pdf_images.sequence:
page = wa(image=img)
page.save(filename=str(page_number) + ".jpg")
page_number += 1
main:
Code: Alles auswählen
from model.presentation import Presentation
if __name__ == "__main__":
presentation = Presentation()
presentation.convert("/home/felix/Schreibtisch/PythonTest/", "kickoff18.pdf", "/home/felix/Schreibtisch/PythonTest/", "neuerOrdner")
print("Run")
Kurz noch zu dem Problem allgemein:
Es soll möglich sein einen neuen Ordner anzulegen, in welchem die Bilder der gesplitteten PDF liegen welche dann wiederrum ausgelesen werden sollen ob in der unteren rechten Ecke genug "weißer" Platz vorhanden ist um ein Video einzufügen, falls das der Fall ist soll das Video eingeblendet werden ansonsten soll das Bild der PDF unverändert dargestellt werden.
Vielen Dank im Vorraus

MfG Felix
Re: Wand TypeError
Verfasst: Freitag 15. März 2019, 19:16
von Sirius3
Die Klasse ist nicht sinnvoll, convert ist eine einfache Funktion.
Pfade setzt man mit os.path.join zusammen nicht mit +.
wa ist eine unlesbare Abkürzung von Image, warum nicht Image lassen?
os.chdir darf in einem Normalen Programm nicht vorkommen, weil es einen globalen Zustand ändert, der an anderen Stellen zu Fehlern führen kann.
Code: Alles auswählen
import os
from wand.image import Image
def convert(path, filename, folder_path, folder_name):
"""a method that takes a path and a PDF file,
converts them to JPG, and then saves the individual images"""
folder = os.path.join(folder_path, folder_name)
os.makedirs(folder)
pdf = Image(filename = os.path.join(path, filename), resolution=300)
pdf_images = pdf.convert("jpeg")
print("Bis hier")
for page_number, img in enumerate(pdf_images.sequence, 1):
page = Image(image=img)
page.save(filename="{}.jpg".format(page_number))
if __name__ == "__main__":
convert("/home/felix/Schreibtisch/PythonTest/", "kickoff18.pdf", "/home/felix/Schreibtisch/PythonTest/", "neuerOrdner")
print("Run")
Hier scheint jemand das selbe Problem gehabt zu haben.
Re: Wand TypeError
Verfasst: Freitag 15. März 2019, 20:25
von Felix92
Huhu Sirius3,
erstmal vielen Dank für deine Antwort hättest du vlt. noch weitere Vorschläge/Anregungen wie ich an den Rest des Problems gehen sollte ich hatte dort an opencv gedacht !?
Und was ich nicht so ganz verstehe ist dieses in enumerate weil woher weiß Python das diese "Bilder" Aufzählungen sein können ? (final static)
Mfg Felix
Re: Wand TypeError
Verfasst: Freitag 15. März 2019, 20:42
von __deets__
Darüber haben wir in deinem andren Thread doch diskutiert. Was von den dort vorgeschlagenen Ansätzen hast du probiert? Was hast du nicht verstanden?
Re: Wand TypeError
Verfasst: Samstag 16. März 2019, 19:28
von Felix92
@Sirius3
Es funktioniert leider immer noch nicht

Getestet mit 2.7 und 3.6:
Code: Alles auswählen
Traceback (most recent call last):
File "main.py", line 5, in <module>
presentation.convert("/home/felix/Schreibtisch/PythonTest/", "kickoff18.pdf", "/home/felix/Schreibtisch/PythonTest/", "neuerOrdner")
File "/home/felix/Schreibtisch/PythonTest/model/presentation.py", line 16, in convert
pdf = Image(filename= os.path.join(path, filename), resolution=300)
File "/usr/lib/python2.7/dist-packages/wand/image.py", line 2744, in __init__
self.read(filename=filename, resolution=resolution)
File "/usr/lib/python2.7/dist-packages/wand/image.py", line 2822, in read
self.raise_exception()
File "/usr/lib/python2.7/dist-packages/wand/resource.py", line 222, in raise_exception
raise e
wand.exceptions.PolicyError: not authorized `/home/felix/Schreibtisch/PythonTest/kickoff18.pdf' @ error/constitute.c/ReadImage/412
Exception TypeError: TypeError("object of type 'NoneType' has no len()",) in <bound method Image.__del__ of <wand.image.Image: (empty)>> ignored
Code: Alles auswählen
Traceback (most recent call last):
File "main.py", line 5, in <module>
presentation.convert("/home/felix/Schreibtisch/PythonTest/", "kickoff18.pdf", "/home/felix/Schreibtisch/PythonTest/", "neuerOrdner")
File "/home/felix/Schreibtisch/PythonTest/model/presentation.py", line 16, in convert
pdf = Image(filename= os.path.join(path, filename), resolution=300)
File "/home/felix/.local/lib/python3.6/site-packages/wand/image.py", line 4708, in __init__
self.read(filename=filename, resolution=resolution)
File "/home/felix/.local/lib/python3.6/site-packages/wand/image.py", line 5002, in read
self.raise_exception()
File "/home/felix/.local/lib/python3.6/site-packages/wand/resource.py", line 222, in raise_exception
raise e
wand.exceptions.PolicyError: not authorized `/home/felix/Schreibtisch/PythonTest/kickoff18.pdf' @ error/constitute.c/ReadImage/412
Ideen woran das liegen kann ?
btw: diese Methode muss sich in einer Klasse befinden, da Sie in einem größeren Projekt eingearbeitet wird
Re: Wand TypeError
Verfasst: Samstag 16. März 2019, 19:46
von Sirius3
Was hast Du denn geändert? Wie sieht die policy-Datei bei Dir aus?
Re: Wand TypeError
Verfasst: Samstag 16. März 2019, 22:10
von __blackjack__
Wobei man sich das ändern der Policy-Datei IMHO gut überlegen sollte. Das wurde ja nicht zum Spass gemacht, sondern um eine Sicherheitslücke zu schliessen, die man damit wieder öffnet.
Re: Wand TypeError
Verfasst: Sonntag 17. März 2019, 10:21
von Felix92
Also wenn ich die Policy-Datei ändere funktioniert es, allerdings ist das nicht Sinn und Zweck, da ich nicht vom "Kunden" erwarten kann die policy.xml zu ändern.
Ich hatte mir kurz die Pillow Doku angesehen allerdings bin ich noch nicht ganz schlau daraus geworden ob es damit auch möglich wäre.
Vlt. hat ja jemand einen Vorschlag wie es relativ simpel ohne wand und Imagick umzusetzen wäre !?
Ich muss dazu sagen das ich allgemein bei Python Librarys in der Anwendungsentwicklung noch ziemlich unerfahren bin, da ich bis auf ein paar einfache Skripte in Python für größere Projekte doch eher Java bevorzuge.
MfG Felix
Re: Wand TypeError
Verfasst: Sonntag 17. März 2019, 11:06
von __deets__
Wenn man deinen Fehler googelt finden sich Alternativen wie pdf2ppm. Schlussendlich Schein ghostscript das Problem zu sein, und das kannst du ggf direkt benutzen in einer Version die repariert ist.
Re: Wand TypeError
Verfasst: Sonntag 17. März 2019, 11:39
von snafu
Felix92 hat geschrieben: Freitag 15. März 2019, 20:25
Und was ich nicht so ganz verstehe ist dieses in enumerate weil woher weiß Python das diese "Bilder" Aufzählungen sein können ? (final static)
enumerate() zählt einfach die Anzahl an Objekten mit und liefert dies als Tupel (Zählerstand, Objekt) zurück. Das spart halt zwei Zeilen bzw lagert das eigentliche Zählen aus. Um es sinnvoll nutzen zu können, muss man das sogenannte Tuple Unpacking in Python verstanden haben.
Re: Wand TypeError
Verfasst: Sonntag 17. März 2019, 12:25
von Felix92
@__deets__ wenn ich das richtig verstanden habe sollte es also reichen die neuste Version von ghostscript zu installieren ? Oder könnte man den Fix für die policy vlt. in einer Methode mit einbinden, so dass der Kunde es nicht selbst ändern muss ?
Re: Wand TypeError
Verfasst: Sonntag 17. März 2019, 12:29
von __deets__
Ersteres musst du ausprobieren. Letzteres kann ich mir nicht vorstellen. Welchen Sinn hätte eine policy, wenn sie so einfach zu umgehen wäre? Dann braucht man sie erst gar nicht.
Re: Wand TypeError
Verfasst: Sonntag 17. März 2019, 13:02
von __blackjack__
@Felix92: Wenn da keine „rolling release“ Linux-Distribiution verwendet wird, kann man ja nicht so einfach eine neuere Ghostscript-Version installieren. Die müsste man dann ja selbst kompilieren oder aus einer externen Paketquelle bekommen. In beiden Fällen wäre dann nicht mehr die Distribution für weitere Bugfixes und Sicherheitsupdates zuständig, sondern man müsste sich das selbst drum kümmern.
Ich persönlich habe dieses Problem auch schon gehabt und bin auf ``pdftoppm`` per `subprocess`-Modul ausgewichen. Wobei sich ein Blick in die manpage lohnt, denn neben PPM kann das auch andere Formate direkt selbst schreiben. Man muss das also beispielsweise nicht in ein ``pnmtojpeg`` pipen um eine JPG-Datei zu erstellen.
Re: Wand TypeError
Verfasst: Sonntag 17. März 2019, 20:28
von Felix92
Es läuft endlich
Code: Alles auswählen
from pdf2image import convert_from_path
import os
class Presentation:
"""Class that divides a PDF into individual images and converts them to jpg"""
def __init__(self):
"""Constructor of the class"""
print('Image erstellt')
pass
def convert(self, path, filename, folder_path, folder_name):
"""a method that creates a new project folder split the pdf to pictures and save them in the new folder"""
folder = os.path.join(folder_path, folder_name)
os.makedirs(folder)
pages = convert_from_path(os.path.join(path, filename), 300)
os.chdir(folder)
page_number = 1
for page in pages:
page.save("{}.jpg".format(page_number), 'JPEG')
page_number += 1
Danke erstmal

Re: Wand TypeError
Verfasst: Sonntag 17. März 2019, 20:48
von __deets__
Du ignorierst mit konsequenz die Hinweise, die dir hier gegeben werden. Dein os.chdir ist problematisch, und den Zähler kannst du besser mit enumerate bekommen.
Re: Wand TypeError
Verfasst: Sonntag 17. März 2019, 21:28
von __blackjack__
Und diese Klasse ist immer noch unsinnig und überflüssig.
Re: Wand TypeError
Verfasst: Sonntag 17. März 2019, 21:55
von __deets__
Na die scheint in ein Framework oä zu gehören. Aber gerade dann ist das manipulieren des current directory erst recht riskant. Wenn andere das auch tun....
Re: Wand TypeError
Verfasst: Sonntag 17. März 2019, 22:59
von Felix92
Ok das mit dem enumerate verstehe ich noch allerdings hatte ich damit Probleme beim sortieren der Bilder und bei chdir weiß ich nicht wie ich sonst in den neu angelegten Ordner schreiben soll !? Die Klasse wird so benötigt, da sie im model des Projekts liegt und da liegt noch ne GUI drüber etc.
Re: Wand TypeError
Verfasst: Sonntag 17. März 2019, 23:02
von sparrow
Felix92 hat geschrieben: Sonntag 17. März 2019, 22:59bei chdir weiß ich nicht wie ich sonst in den neu angelegten Ordner schreiben soll !?
Indem du den kompleten Pfad der zur Datei und nicht nur den Dateinamen angibst.
Re: Wand TypeError
Verfasst: Montag 18. März 2019, 14:53
von DeaD_EyE
Edit: Dein Programm kann überall dort hinschreiben, zu dem es auch die entsprechenden Berechtigungen hat.
Das aktuelle Verzeichnis zu wechseln ist überhaupt nicht notwendig. Das muss man nur machen, wenn man irgendwelche schlechten Bibliotheken nutzt, die einem keine andere Wahl lassen.
Code: Alles auswählen
from pdf2image import convert_from_path
from pathlib import Path
def convert(path, filename, folder_path, folder_name):
"""a function that creates a new project folder split the pdf to pictures and save them in the new folder"""
folder = Path(folder_path, folder_name)
folder.mkdir(exist_ok=True)
input_file = Path(path, filename)
pages = convert_from_path(str(input_file), 300)
for page_number, page in enumerate(pages, start=1):
target = folder / f"{page_number:03d}.jpg"
page.save(str(target), 'JPEG')
Ich bin ein pathlib-faschist.
Code ist nicht getestet. Wenn man noch alte Bibliotheken verwendet, müssen die Path Objekte zuvor in einen String umgewandelt werden.
Das aktuelle Verzeichnis zur Laufzeit des Programms zu wechseln, ist eine ganz schlechte Idee. Eine Klasse mit zwei Methoden ist keine Klasse.
Das ignorieren von Vorschlägen führt dazu, dass du vieles per Hand machst (enumerate z.B.).
Überlege dir andere Namen für die Variablen. path, filename, folder_path, folder_name kann alles mögliche sein.
Nutze nicht die ungarische Notation.