IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

Vous êtes nouveau sur Developpez.com ? Créez votre compte ou connectez-vous afin de pouvoir participer !

Vous devez avoir un compte Developpez.com et être connecté pour pouvoir participer aux discussions.

Vous n'avez pas encore de compte Developpez.com ? Créez-en un en quelques instants, c'est entièrement gratuit !

Si vous disposez déjà d'un compte et qu'il est bien activé, connectez-vous à l'aide du formulaire ci-dessous.

Identifiez-vous
Identifiant
Mot de passe
Mot de passe oublié ?
Créer un compte

L'inscription est gratuite et ne vous prendra que quelques instants !

Je m'inscris !

Comment créer un filigrane transparent en PDF ?
Par blowagie

Le , par blowagie

0PARTAGES

QUESTION:
Je dois ajouter un filigrane à chaque page d'un fichier PDF. Le filigrane peut être du texte ou une image, mais doit surtout être transparent. Comment puis-je obtenir de de tels filigranes en PDF?
(Pour la version anglaise, voir How to watermark PDFs using text or images?)

REPONSE:
Jetons un oeil à l'exemple TransparentWatermark2. Dans cet example, on prend un document PDF existant et on ajoute un texte transparent sur chaque page impaire et une image transparente sur chaque page paire:

Code : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
public void manipulatePdf(String src, String dest) throws IOException, DocumentException {
    PdfReader reader = new PdfReader(src);
    int n = reader.getNumberOfPages();
    PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(dest));
    // text watermark
    Font f = new Font(FontFamily.HELVETICA, 30);
    Phrase p = new Phrase("My watermark (text)", f);
    // image watermark
    Image img = Image.getInstance(IMG);
    float w = img.getScaledWidth();
    float h = img.getScaledHeight();
    // transparency
    PdfGState gs1 = new PdfGState();
    gs1.setFillOpacity(0.5f);
    // properties
    PdfContentByte over;
    Rectangle pagesize;
    float x, y;
    // loop over every page
    for (int i = 1; i <= n; i++) {
        pagesize = reader.getPageSizeWithRotation(i);
        x = (pagesize.getLeft() + pagesize.getRight()) / 2;
        y = (pagesize.getTop() + pagesize.getBottom()) / 2;
        over = stamper.getOverContent(i);
        over.saveState();
        over.setGState(gs1);
        if (i % 2 == 1)
            ColumnText.showTextAligned(over, Element.ALIGN_CENTER, p, x, y, 0);
        else
            over.addImage(img, w, 0, 0, h, x - (w / 2), y - (h / 2));
        over.restoreState();
    }
    stamper.close();
    reader.close();
}
Commençons avec un PdfReader (ligne 2) et un PdfStamper (ligne 4). L'object reader va lire le document existent et l'objet stamper va créer le document modifié.

Ensuite nous construisons
  • une Phrase avec le texte "My watermark (text)" (ligne 7) et une police Helvetica avec taille 30pt (ligne 6).
  • une Image dont on le chemin de fichier est IMG (ligne 9); w et h sont la largeur et la hauteur de l'image (line 10 et 11).
  • un objet PdfGState (ligne 13) qui contient la valeur de la transparence: une opacité de 50% (ligne 14). Ceci is l'état graphique (graphics state) du contenu d'une page PDF.

Une fois que nous avons ces objets, nous visitons chaque page (ligne 20). En général, nous utilisons l'objet reader pour obtenir des informations sur le document existant, par exemple les dimensions de chaque page (ligne 21). Nous utilisons l'objet PdfStamper quand nous voulons ajouter du contenu supplémentaire au document existant, par exemple l'ajout d'un filigrane.

Lors du changement du graphics state, il est toujours plus sûr d'effectuer saveState() avant de commencer et restoreState() une fois que vous avez terminé. Si vous supprimez ligne 25 et 31, l'application fonctionnera probablement sans fautes, mais croyez-moi: il vaut mieux d'avoir ces deux lignes afin d'éviter devoir déboger votre code en cas d'effets étranges avec un état graphique non-équilibré.

Nous appliquons la transparence en utilisant la méthode setGState() (ligne 26) et selon que la page est une page impaire ou paire, nous ajoutons:
  • le texte en utilisant ColumnText et le coordonnées (x, y) calculée de sorte que le texte est ajouté dans le milieu de chaque page (ligne 28), ou
  • l'image en utilisant la methode addImage() et les paramètres appropriés pour la matrice de transformation (ligne 30).

Une fois que nous avons executé ceci pour chaque page du document, nous fermons le stamper (ligne 33) et le reader (ligne 34).

Regardons le résultat: nous avions un fichier pages.pdf au quel nous avons ajouté ces filigranes. Le résultat est le fichier pages_watermarked.pdf dont la page 3 et 4 sont présentés dans la capture d'écran ci-dessous:



Si vous examinez le fichier PDF de plus près, vous remarquerez que les pages 3 et 4 sont dans le format paysage, mais il ya une différence entre ces deux pages qui n'est pas visible du premier coup d'œil. Page 3 est en fait une page dont la taille est définie comme s'il s'agissait d'une page en mode portrait, mais la page est tourné de 90 degrés. Page 4 est une page dont la dimension est définie de telle sorte que la largeur est plus large que la hauteur (un vrai format paysage). Cette différence peut avoir des conséquences si vous ajoutez un filigrane.

En utilisant getPageSizeWithRotation(), iText s'adaptera, mais ceci n'est peut-être pas tout à fait ce que vous voulez: peut-être vous souhaitez que le filigrane tourne de la même façon que la page:


La capture d'écran nous montre que la page de gauche est en fait une page en format portrait, tournée de 90 degrees. En consequent, nous voulons peut-être que le filigrane est tourné aussi. (La page de droite est une page en format paysage, le filigrane ne doit pas être tourné.)

Comment obtenir ce résultat? Il suffit remplacer la méthode getPageSizeWithRotation() par la méthode getPageSize() et de forcer le PdfStamper de ne pas tenir compte de la rotation de la page: stamper.setRotateContents(false);

Voyons ligne 5 et ligne 22 de l'example TransparentWatermark3:

Code : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
public void manipulatePdf(String src, String dest) throws IOException, DocumentException {
    PdfReader reader = new PdfReader(src);
    int n = reader.getNumberOfPages();
    PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(dest));
    stamper.setRotateContents(false);
    // text watermark
    Font f = new Font(FontFamily.HELVETICA, 30);
    Phrase p = new Phrase("My watermark (text)", f);
    // image watermark
    Image img = Image.getInstance(IMG);
    float w = img.getScaledWidth();
    float h = img.getScaledHeight();
    // transparency
    PdfGState gs1 = new PdfGState();
    gs1.setFillOpacity(0.5f);
    // properties
    PdfContentByte over;
    Rectangle pagesize;
    float x, y;
    // loop over every page
    for (int i = 1; i <= n; i++) {
        pagesize = reader.getPageSize(i);
        x = (pagesize.getLeft() + pagesize.getRight()) / 2;
        y = (pagesize.getTop() + pagesize.getBottom()) / 2;
        over = stamper.getOverContent(i);
        over.saveState();
        over.setGState(gs1);
        if (i % 2 == 1)
            ColumnText.showTextAligned(over, Element.ALIGN_CENTER, p, x, y, 0);
        else
            over.addImage(img, w, 0, 0, h, x - (w / 2), y - (h / 2));
        over.restoreState();
    }
    stamper.close();
    reader.close();
}
Maintenant le filigrane va suivre l'orientation de chaque page.

Si vous voulez plus d'exemples iText comme celui-ci, téléchargez le livre gratuit The Best iText Questions on StackOverflow.

Une erreur dans cette actualité ? Signalez-nous-la !