Une extension de la merveilleuse bibliothèque PDFRW qui ajoute la manipulation des flux de contenu (et tous les objets référencés là-bas, par exemple des images, des polices, etc.) tout en le gardant aussi simple que possible.
Alors, pourquoi étendre PDFRW alors qu'il existe des bibliothèques PDF à part entière comme le PYPDF? Pensez-y de cette façon: la plupart des bibliothèques PDF essaient de fournir des fonctions qui simplifient les tâches de traitement PDF courantes. Ces bibliothèques sont très bonnes dans ce qu'elles font, mais de temps en temps, une tâche apparaît qui nécessite une nouvelle fonction. Maintenant, si vous êtes un développeur qui se trouve dans une telle situation, vous devez commencer à creuser dans de grandes quantités de code source de ces bibliothèques.
L'approche de PDFRW est différente: analysons le PDF autant que possible, tout en gardant le résultat aussi simple que possible. Pas une mauvaise idée, surtout étant donné le fait que le modèle d'objet PDF (qui n'est qu'un tas de dictionnaires avec certaines de leurs valeurs étant des références à d'autres dictionnaires) est très bien adapté à la cartographie des dictionnaires Python standard. En plus de cela, PDFRW met en œuvre une idée derrière un autre merveilleux package d'attaque pour rendre les objets PDF traversant encore plus simples: l'accès aux polices de page, par exemple, peut maintenant être fait comme ceci:
for fontName , fontDict in page . Resources . Font . items ():
( do something )L'étape suivante consiste à essayer d'analyser les flux de dictionnaires - ce sont des entrées spéciales dans les dictionnaires qui contiennent les choses intéressantes: texte, images, graphiques vectoriels, etc. PDFRW ne fait rien de tout cela, et il ne le fait pas exprès: conformément à sa philosophie de type Unix, elle fait ce qu'elle fait très bien, et ne fait pas un peu plus. La structure de données qu'il produit est complète: elle contient tout le PDF, suffisamment pour toute tâche de traitement possible. Et c'est assez simple pour que le développeur puisse commencer à coder immédiatement, passer plus de temps à profiter des passages dans le magnum opus d'Adobe, et aucun - apprendre une autre bibliothèque compliquée. Et, en fait, PDFRW est un outil idéal pour aider à apprendre la syntaxe PDF en jouant avec!
OK, si vous en arrivez à ce point, alors vous vous demandez les chances: alors, où dois-je aller d'ici? Plus précisément: comment analyser les flux du dictionnaire? C'est là que PDFRWX peut aider: il peut analyser les flux de dictionnaire et faire d'autres choses utiles. Mais d'abord les choses d'abord:
PDFRWX d'abord et avant tout essaie de rester avec la philosophie de PDFRW décrite ci-dessus. À cela, cela ajoute une observation que dans de nombreuses tâches de traitement PDF, la plupart du temps est consacré à développer une solution logicielle et non à l'exécuter. Cela conduit aux choix de conception:
Maintenant, nous sommes prêts à voir ce que fait PDFRWX et comment il y parvient:
Voici des exemples / exemple-pdfstream.py qui lit Example.pdf, supprime tout le contenu texte de chaque page et écrit le résultat à Exemple-out.pdf:
from pdfrw import PdfReader , PdfWriter , PdfArray
from pdfrwx . pdffilter import PdfFilter
from pdfrwx . pdfstreamparser import PdfStream
toArray = lambda obj : obj if isinstance ( obj , PdfArray )
else PdfArray ([ obj ]) if obj != None else PdfArray ()
pdfIn = PdfReader ( 'example.pdf' )
pdfOut = PdfWriter ( 'example-out.pdf' )
for page in pdfIn . pages :
contentsArray = toArray ( page . Contents )
for contents in contentsArray :
stream = PdfFilter . uncompress ( contents ). stream
treeIn = PdfStream . stream_to_tree ( stream )
treeOut = []
for leaf in treeIn :
cmd , args = leaf [: 2 ]
if cmd != 'BT' : treeOut . append ( leaf )
contents . stream = PdfStream . tree_to_stream ( treeOut )
contents . Filter = None
pdfOut . addPage ( page )
pdfOut . write ()Comme vous pouvez le voir, le code passe au-dessus des pages, puis sur le contenu de chaque page, puis incompte le contenu, car il peut être comprimé, puis analyse le flux de contenu dans une arborescence, supprime les blocs de texte BT / ET, puis analyse l'arbre résultant en flux. La signification de chaque ligne de code ci-dessus doit être claire en dehors de la fonction de lambda TOARRAY: elle est là parce qu'une page en PDF peut avoir plus d'un dictionnaire de contenu, auquel cas Page.Contents est un PDFARRAY, et chacun de ses éléments doit être traité séparément. Et donc, la fonction TOARRAY LAMBDA rend la situation avec le contenu de la page plus uniforme en tournant la page. Contents qui ne sont pas des tableaux en pdfarray avec un élément.
Quelques autres choses doivent également être notées. Tout d'abord, notez que pour accomplish la tâche, le code utilise seulement deux nouvelles classes de PDFRWX : PDFFILTER et PDFSTERM, avec un / deux appels de fonction de chacun. Deuxièmement, l'arbre analysé I juste une liste de python standard imbriquée du format trivial suivant:
[
['q', []],
['cm', ['1','0','0','1','0','0']],
...
['BT', [], [ /a tree list of text operators/ ]],
...
['Q', []]
]
Ainsi, chaque feuille (élément) de la liste des arbres est elle-même une liste de 2 ou 3 éléments: les deux premiers éléments sont la commande et la liste des arguments (une liste vide si la commande n'a pas d'arguments), tandis que le troisième argument facultatif est présent dans le cas où la feuille est un bloc de commandes, dans quel cas c'est la liste des arbres des commandes qui composent le bloc. Par conception, il n'y a que deux types de blocs: le bloc de texte BT / ET, qui utilise le nom de commande «BT» dans l'arbre analysé, et le bloc d'image en ligne Bi / ID / EI, qui utilise le nom de commande «Bi» dans l'arbre analysé. Notez que dans le flux PDF original, il n'y a qu'une séquence de commandes; C'est l'analyseur PDFStream qui crée ces blocs dans sa sortie pour plus de commodité. Pour vous familiariser davantage avec la structure de la sortie de l'analyseur de flux, essayez d'insérer une commande comme Pprint (Treein) juste après l'appel à l'analyseur.
Notez également que la fonction TOARRAY , aussi utile, n'a pas été implémentée dans le module, et vous devez donc le coder à chaque fois que vous faites l'analyse. Cela peut sembler étrange, mais c'est le résultat des mêmes principes de conception: le module analyse simplement le flux; C'est au développeur de coder tout le reste.
La classe PDFStream Parser est implémentée dans Pure Python en utilisant environ 300 lignes de code à l'aide de la bibliothèque de générateurs PARSER populaire (et pur Python!) Par David Beazley - consultez ses conférences sur YT, il est formidable! Pour le curieux: l'analyseur utilise deux états d'analyseurs (c'est-à-dire deux analyseurs différents avec des grammaires différentes qui basculent entre elles comme ils fonctionnent), l'une pour l'analyse des cordes littérales PDF (c'est-à-dire des chaînes qui sont entre parenthèses), et l'autre - pour tout le reste. Oui, afin que les chaînes littérales prennent en charge les parenthèses de codage dans le cadre de la chaîne, le format des chaînes littérales PDF a été rendu si complexe qu'il nécessitait un analyseur séparé juste pour analyser ceux-ci. Donc, si pour une raison quelconque (vitesse?) Vous voudrez jamais implémenter l'analyseur de flux à l'aide d'une autre bibliothèque de générateurs d'analyse, assurez-vous qu'il prend en charge une pile pour les états d'analyse.
Résout l'enfer des polices. Docs à venir bientôt, restez à l'écoute.
Filtres pris en charge:
Vous en avez assez des bogues des produits d'Adobe en ce qui concerne la précision des couleurs dans l'exportation d'images? Ensuite, vous êtes venu au bon endroit! Visant à être la classe de manipulation d'image PDF la plus précise de tous. Docs à venir bientôt, restez à l'écoute.
Codecs pris en charge (encode / décodage):
Espaces de couleur pris en charge:
Plus:
Le module est parfaitement utilisable pour le moment et a été effectué à travers une multitude de tests pour s'assurer qu'il fait ce qu'il promet de faire correctement. Cependant, il n'est en aucun cas près de l'alpha: les interfaces ne sont pas encore entièrement finalisées. De plus, le traitement des erreurs est rompu (sera probablement résolu bientôt et fait de la même manière que les erreurs sont gérées dans PDFRW ). Donc, Jouez à vos risques et périls Aucun risque, ne vous attendez pas à ce qu'il soit encore de qualité de production.