Internes du moteur de traitement PDF

Internes du moteur de traitement PDF

Internaux du moteur de traitement PDF

Les classes Document, Page et Annotation que vous utilisez pour le traitement quotidien des PDF sont une façade sur un package aspose_pdf.engine de niveau inférieur. Le moteur implémente les mécanismes réels du PDF: le modèle d’objet COS (Carousel Object Structure) dont chaque fichier PDF est construit, l’analyseur et l’écrivain qui convertissent entre les objets COS et les octets PDF, la synthèse de l’apparence des annotations, la rasterisation des pages, les internes des codecs de polices et d’images, ainsi que les primitives cryptographiques derrière le chiffrement des documents et les signatures numériques. La plupart des applications n’ont jamais besoin d’importer directement depuis aspose_pdf.engine — mais c’est l’endroit approprié à consulter lorsque vous avez besoin d’outils personnalisés, d’une inspection médico-légale de PDF, ou d’un comportement que le API de haut niveau n’expose pas.


Génération d’une apparence pour une annotation unique

Les annotations interactives telles que les carrés, les cercles et les tampons ne contiennent pas automatiquement un flux d’apparence normal (/AP /N). Appeler Annotation.generate_appearance déclenche les internes de synthèse d’apparence du moteur pour en créer un à la demande à partir des propriétés de l’annotation.

from aspose_pdf import Document

doc = Document()
doc.pages.add()
ann = doc.pages[0].annotations.add(
    "Square", (100, 100, 200, 200), "", properties={"C": [1, 0, 0], "IC": [0, 1, 0]}
)

print(ann.has_appearance)  # False -- no appearance stream yet
ann.generate_appearance()
print(ann.has_appearance)  # True -- the engine synthesised one
print(b"1 0 0 RG" in ann.appearance_normal)  # True -- red stroke operator
print(b"0 1 0 rg" in ann.appearance_normal)  # True -- green fill operator

Génération par lots d’apparences à travers les pages et les documents

AnnotationCollection.generate_appearances synthétise les apparences pour chaque annotation admissible sur une page en un seul appel, en sautant les sous-types que le moteur ne sait pas rendre (comme Text):

from aspose_pdf import Document

doc = Document()
doc.pages.add()
page = doc.pages[0]
page.annotations.add("Square", (0, 0, 50, 50), "")
page.annotations.add("Circle", (60, 0, 110, 50), "")
page.annotations.add("Text", (0, 60, 20, 80), "")  # unsupported subtype -> skipped

print(page.annotations.generate_appearances())  # 2

Document.generate_appearances fait de même sur chaque page du document, et est idempotent — un second appel ne fait rien une fois les apparences déjà présentes:

from aspose_pdf import Document

doc = Document()
doc.pages.add()
doc.pages.add()
doc.pages[0].annotations.add("Square", (0, 0, 50, 50), "")
doc.pages[1].annotations.add(
    "Line", (0, 0, 50, 50), "", properties={"L": [0, 0, 50, 50]}
)

print(doc.generate_appearances())  # 2 -- one per page
print(doc.generate_appearances())  # 0 -- already generated, no-op

Aplatissement des annotations dans le contenu de page statique

Document.flatten() dessine l’apparence de chaque annotation directement dans le flux de contenu de sa page (comme une invocation XObject Do) et supprime ensuite l’objet annotation lui-même, de sorte que la page s’affiche identiquement dans les visionneuses qui ignorent complètement les annotations :

from aspose_pdf import Document

doc = Document()
doc.pages.add()
doc.pages[0].annotations.add(
    "Square", (100, 100, 200, 200), "", properties={"C": [0, 0, 0]}
)

doc.flatten()

Après cet appel, le flux de contenu de la page est plus long qu’auparavant (il contient désormais le carré intégré) et doc.pages[0].annotations ne contient plus l’annotation aplatie.


Dérivation des clés de chiffrement basées sur le mot de passe (Révision 4 / AES-128)

EncryptionUtils implémente directement la dérivation de clés du gestionnaire de sécurité standard PDF et les primitives AES-CBC, indépendamment du Document API. Cela est utile pour des outils personnalisés ou une inspection légale de PDFs chiffrés :

import os
from aspose_pdf.engine.encryption import EncryptionUtils

file_id = os.urandom(16)
user_pwd = "mypassword"

# Derive the owner (O) and user (U) key material for Revision 4 (128-bit AES)
o_value = EncryptionUtils.compute_owner_key_v4("owner", user_pwd, 16, 4)
u_value, enc_key = EncryptionUtils.compute_user_key_v4(
    user_pwd, o_value, -4, file_id, 16, 4
)

# Encrypt data with the derived file-encryption key
plaintext = b"Confidential PDF content"
ciphertext = EncryptionUtils.encrypt_aes_cbc(enc_key, plaintext)

# Re-derive the key from the password before trusting it to decrypt
verified_key = EncryptionUtils.verify_password_v4(
    user_pwd, u_value, o_value, -4, file_id, 16, 4
)
print(verified_key is not None)  # True -- password matches

decrypted = EncryptionUtils.decrypt_aes_cbc(verified_key, ciphertext)
print(decrypted == plaintext)  # True

Chiffrement du contenu brut avec AES-CBC

Pour des besoins de bas niveau, EncryptionUtils.encrypt_aes_cbc() et decrypt_aes_cbc() travaillent directement sur toute clé de 16, 24 ou 32 octets sans passer par la dérivation de clé basée sur le mot de passe du tout :

import os
from aspose_pdf.engine.encryption import EncryptionUtils

key = os.urandom(32)  # AES-256; 16 and 24-byte keys are also accepted
plaintext = b"Hello, PDF AES 256!"

ciphertext = EncryptionUtils.encrypt_aes_cbc(key, plaintext)
decrypted = EncryptionUtils.decrypt_aes_cbc(key, ciphertext)
print(decrypted == plaintext)  # True

Conseils et meilleures pratiques

  • Privilégiez la façade de haut niveau Document, Page et Annotation pour le traitement quotidien des documents. Le package aspose_pdf.engine est l’implémentation interne sur laquelle ces classes sont construites — ne l’utilisez que lorsque vous avez besoin d’outils personnalisés, d’une inspection médico-légale ou d’un comportement que la façade n’expose pas.
  • Faites correspondre l’argument revision au gestionnaire de sécurité que vous ciblez: compute_owner_key_v4/compute_user_key_v4 couvrent les Révisions 2–4 (RC4/AES 40 bits et 128 bits), tandis que compute_hash_v5 implémente l’algorithme des Révisions 5/6 utilisé par AES-256. Mélanger les révisions et les longueurs de clé produit silencieusement la mauvaise clé.
  • Document.generate_appearances et AnnotationCollection.generate_appearances sont idempotents — appelez-les de manière défensive avant de rendre ou d’aplatir un document que vous n’avez pas créé vous-même.
  • Document.flatten() est destructif: il supprime chaque annotation qu’il insère dans le contenu de la page. Terminez d’abord toute autre modification d’annotation, ou travaillez sur une copie.
  • Tous les sous-types d’annotation n’ont pas de synthétiseur d’apparence intégré — Text et Popup en sont des exemples courants. Vérifiez has_appearance après avoir appelé generate_appearance() au lieu de supposer qu’il a réussi.

Problèmes courants

ProblèmeCauseCorrection
EncryptionUtils.encrypt_aes_cbc/decrypt_aes_cbc génère une erreur “AES key must be 16, 24, or 32 bytes”Une clé d’une longueur invalide a été fournieGénérez la clé avec os.urandom(16), os.urandom(24) ou os.urandom(32)
EncryptionUtils.verify_password_v4 renvoie None au lieu de leverLe mot de passe fourni ne correspond pas aux valeurs U/O dérivées du documentVérifiez explicitement None avant de transmettre le résultat à decrypt_aes_cbc
Annotation.generate_appearance renvoie FalseLe sous-type de l’annotation n’a pas de synthétiseur d’apparence intégré (par exemple Text ou Popup)Fournissez vos propres octets appearance_normal, ou acceptez le rendu par défaut du visualiseur
Un deuxième appel à Document.generate_appearances renvoie 0L’appel est idempotent — les annotations qui possèdent déjà has_appearance == True sont ignoréesComportement attendu, pas une erreur

FAQ

Dois-je importer depuis aspose_pdf.engine pour le traitement quotidien des documents ?

Non. Les classes Document, Page et Annotation couvrent les flux de travail standard des documents. La couche moteur est l’endroit où le comportement de ces classes est implémenté, et elle est la plus utile pour les outils personnalisés ou l’inspection directe des internes du PDF.

Quelle est la différence entre Annotation.generate_appearance et AnnotationCollection.generate_appearances?

Le premier synthétise un flux d’apparence pour une annotation unique et renvoie un bool. Le second fait de même pour chaque annotation admissible dans une collection (les annotations d’une page, ou, via Document.generate_appearances, chaque page du document) et renvoie le nombre d’apparences qu’il a créées.

Pourquoi les méthodes de dérivation de clé prennent-elles un argument revision?

Le gestionnaire de sécurité du standard PDF a évolué au fil des révisions de la norme ISO 32000 — la révision 2 utilise le RC4 à 40 bits, les révisions 3/4 supportent le RC4 à 128 bits ou l’AES, et les révisions 5/6 (utilisées pour AES-256) utilisent un algorithme de hachage entièrement différent (compute_hash_v5). L’argument revision sélectionne quelle dérivation les méthodes EncryptionUtils effectuent.

Puis-je inspecter ou construire des objets PDF bruts directement?

Oui. aspose_pdf.engine.cos expose le modèle d’objet COS — PdfObject, PdfDictionary, PdfArray, PdfStream, PdfName et les types associés — que PdfCosWriter et PdfCosParser sérialisent en octets PDF et analysent à partir de ceux-ci.

Où se produit le rendu page-vers-image?

Document.render_page renvoie un RasterizedPage, un objet au niveau du moteur avec les méthodes to_png(), to_tiff() et save() pour transformer une page rendue en fichier image.


API Reference Résumé

Classe / MéthodeDescription
Annotation.generate_appearance(force) -> boolSynthétiser le flux d’apparence normal pour une annotation à la demande
AnnotationCollection.generate_appearances(force) -> intGénérer en lot les apparences pour chaque annotation éligible sur une page
Document.generate_appearances(force) -> intGénérer en lot les apparences pour chaque annotation éligible dans le document
Document.flatten() -> DocumentIntégrer les apparences d’annotation dans le contenu de la page et supprimer les annotations
Document.render_page(page_index, dpi, scale, background, antialias) -> RasterizedPageRasteriser une page à travers le pipeline de rendu du moteur
RasterizedPageUne page rendue au format RGB empaqueté, avec to_png(), to_tiff() et save()
GeneratedAppearanceRésultat interne de la synthèse d’apparence : octets de contenu plus toutes les ressources ExtGState/font requises
EncryptionUtilsChiffrement AES-CBC/RC4 et dérivation de clé du standard-security-handler PDF (Révisions 2–6)
PdfObjectClasse de base abstraite pour chaque objet COS (Carousel Object Structure)
PdfDictionary / PdfArray / PdfStreamTypes de conteneurs COS concrets qui composent l’arbre de document de bas niveau
PdfName / PdfNumber / PdfString / PdfBoolean / PdfNullTypes de valeurs COS primitives
PdfIndirectReferenceUne référence indirecte COS (n g R) vers un autre objet
PdfCosWriterSérialise un COS PdfDocument en mémoire en octets PDF
PdfCosParser / LazyPdfObjectStoreAnalyse les octets PDF en objets COS, les matérialisant à la demande
IncrementalUpdate / IncrementalWriterAjoute une section de mise à jour incrémentielle à un PDF existant au lieu de le réécrire
SimplePdfLa représentation native-Python bas-niveau du document sur laquelle le Document API de haut niveau est construit
TextFragmentAbsorber / TextFragmentCollectionExtraction de fragments de texte de bas niveau sur une instance SimplePdf
ImagePlacementAbsorber / ImagePlacementLocaliser, enregistrer, remplacer ou masquer les images matricielles placées sur une page
SigningUtilsGénérer des certificats auto-signés et des signatures PKCS#7/CAdES pour la signature numérique
DssMaterial / ChainResult / RevocationResult / TimestampInfoPrise en charge de la validation des signatures : matériel DSS, résultats de chaîne de certificats, vérifications de révocation et validation des horodatages RFC 3161
StandardFontsMétriques et encodages pour les 14 polices standard PDF
CidTextCodecEncoder et décoder les show-strings pour les polices composites (Type0)
ShadingÉchantillonner la couleur RGB sur les dégradés axiaux, radiaux et basés sur des fonctions
Color / MatrixPrimitives de couleur de bas niveau et de transformation affine 2-D utilisées dans tout le moteur

Voir aussi

 Français