[Résolu] Modification d'un fichier pdf existant
Bonjour à tous,
Voilà , je suis en train de développer une petite application qui doit permettre de rédiger des documents pdf à partir de modèles. Je me suis donc plongée dans la documentation sur le sujet, et j'ai pas mal progressé, mais là je suis en train de me noyer.
J'arrive à créer un nouveau document pdf et à y écrire ce que je veux, donc pour les méthodes qui permettent d'écrire un truc dans un nouveau pdf, tout va bien. Par contre, j'aimerais éviter de recréer l'ensemble du document à chaque fois, et j'aimerais donc repartir d'un document existant (modèle).
Donc, je cherche la méthode (si elle existe) et sa syntaxe, pour ouvrir un document pdf existant et créer un context à partir de ce pdf... Une petite piste ?
Merci d'avance
Réponses
Bonjour,
Il me semble que le plus simple est de réécrire ou redessiner "sur" l'original.
Donc créer un nouveau pdf, dessiner l'original dedans, puis ce qui doit être ajouté.
Oui, je suis d'accord avec toi. Mon problème est que je ne sais pas récupérer le modèle...
Je sais créer un nouveau fichier avec UIGraphicsBeginPDFContextToFile(pdfPath, CGRectZero, nil), je sais y écrire, créer des nouvelles pages, dessiner et importer des images dans ce nouveau pdf... mais je ne sais pas y copier mon modèle (qui se trouve dans le bundle). En fait, il me manque juste la méthode qui permet de faire çà ! Et je dois avoir les neurones en court-circuit, mais je ne trouve pas çà dans la doc !
Merci de ton aide.
Bon, j'ai un peu avancé, mais ce n'est pas encore çà ! Voici le code :
Avec la méthode addText :
Le problème, c'est que mon modèle s'affiche à l'envers (comme si je le regardais dans un miroir... Alors évidemment, le texte que j'insère qui est lui dans la bon sens, n'est pas positionné au bon endroit !
Qu'est-ce que je fais de travers ?
Merci d'avance.
1) Attention à respecter la Create Rule. On a tendance à l'oublier maintenant que le monde Cocoa/Objet fait tout tout seul avec ARC, mais dans le monde C, toujours balancer les fonctions XXXCreate() et XXXCopy() par un CFRelease(). Or dans ton code je vois entre autres CGPDFDocumentCreateWithURL(...) sans CFRelease associé, et de même pour un CFBundleCopyResourceURL.
2) Je ne connais pas l'API de CGPDF, mais ça m'étonne un peu qu'un UIGraphicsBeginPDFPageWithInfo n'ait pas à être balancé avec une fonction opposée du genre UIGraphicsEndPDFPage, comme la plupart des méthodes XXXBeginYYY sont en général balancées par un XXXEndYYY ?
---
[EDIT]
Sinon, pour ton problème de retournement, c'est très certainement une histoire de référenciel de coordonnées, certains contextes ayant leur origine en bas à gauche et les Y croissants vers le haut (genre CoreGraphics), d'autres ont leur origine en haut à gauche et les Y croissants vers le bas (genre UIKit).
Du coup il faut certainement que tu appliques un CGAffineTransform à ton CGContextRef pour le retourner (Scale(1,-1) pour inverser les Y + Translate(height) pour recaler l'origin, le seul truc c'est que je ne sais jamais dans quel sens mais bon à tâtons on finit toujours par retrouver).
Ce qui d'ailleurs donnerait une utilité à tes appels à CGContextSaveGState() et CGContextRestoreGState() qui sinon ne servent pas à grand chose vu qu'entre ces 2 appels tu ne modifies pas le contexte dans ton code actuel (pas de transformation, ni de changement de strokeColor et/ou fillColor, etc). Alors qu'en rajoutant la transformation pour mettre ton contexte dans le bon sens avant de dessiner ton PDF modèle dedans, ça aura une utilité de sauver son état avant la transformation et restaurer son état après
Désolé pour ce délai de réponse.
Dans mon cas je dois stocker le pdf dans mon fichier donc je le charge ainsi :
où mPicture est un de mes propres objets de dessin.
Puis pour dessiner le pdf :
x1, x2, y1 ,y2 sont les 2 coins opposés de l'image dans mon repère global.
zoomFactor est le coefficient de zoom du dessin.
Je ne dessine que la première page du pdf.
Voilà .
Voilà çà y est, j'ai fini par réussir ce que je voulais faire. Merci à tous les deux, vous m'avez mis sur la piste.
@AliGator : tu avais raison, il y avait bien une histoire de référentiel différent. Les pdf utilisent comme origine le bas de page à gauche... et il fallait donc bien faire un changement de référentiel avant d'écrire le pdf, mais par contre, ce que je n'avais pas compris, c'est qu'il fallait que je remette le bon référentiel avant d'écrire mes propres textes !
Voilà ce que çà donne, çà pourra surement aider quelqu'un un jour :
CGContextRestoreGState(context);
// Page 2
CGRect cadreNewPage=CGRectMake(0., 0., _pageSize.width, _pageSize.height);
UIGraphicsBeginPDFPageWithInfo(cadreNewPage, nil); [self addText:@Mon super texte à ajouter sur la page 2 withFrame:CGRectMake(kMarginLeft+kDeltaX, kMarginTop +kDeltaY, kWidth, kHeight) withAttributes:textAttributes]; // Inversion du contexte pour pouvoir y dessiner la page 2 du pdf [self invertContextForPdf:context]; // Récupération de la deuxième page du modèle pdf
CGPDFPageRef page2 = CGPDFDocumentGetPage(pdfDocumentModele, 2);
CGContextDrawPDFPage(context, page2);
avec la méthode d'inversion du contexte :
Voilà , je n'ai plus qu'à regarder de plus près le problème des CFRelease et le contexte "restore", parce que là , c'est pas trop çà !
Je reviendrai corriger ce code lorsque ce sera résolu !
Merci de votre aide en tout cas...
Edit : petit problème avec les balises code... j'arrive pas à le résoudre ! désolée pour la lisibilité...
D'autant que tu pourrais imaginer avoir des erreurs d'arrondi.
Il y a les fonctions CGContextSaveGState() et CGContextRestoreGState() pour ça : la première "mémorise" l'état du contexte (repère, rotation, fillcolor, strokecolor, lineWidth, ...), la 2e restore l'état précédemment mémorisé.
Donc typiquement, tu CGContextSaveGState(), puis tu inverses ton contexte, juste le temps de dessiner ton PDF, et enfin, au lieu de ré-inverser à nouveau ton contexte, tu restores ton contexte avec CGContextRestoreGState() pour retourner dans l'état avant l'inversion.
Ah OK merci, je vais changer ça ; j'editerai mon message quand je serai sur mon Mac. Sur l'iPhone c'est un peu trop compliqué !
Edit : çà y est j'ai édité mon message précédent, et du coup, il y a de nouveau des problèmes avec les balises "code". Du coup, c'est de nouveau illisible...
C'est moi, ou c'est un bug du forum ?
J'utilise ces deux fonctions.
Effectivement je n'ai pas copié tout mon code mais uniquement la partie de dessin du pdf lui-même puisque j'ai aussi le dessin des poignées si l'objet est sélectionné.