Come aggiungere testo a un’immagine?

Nel mio progetto utilizzo iText per generare un documento PDF.

Supponiamo che l’altezza di una pagina sia di 500 punti (1 unità utente = 1 punto) e che scrivo del testo sulla pagina, seguito da un’immagine.

Se il contenuto e l’immagine richiedono meno di 450 pt, il testo ha preceduto l’immagine. Se il contenuto e l’immagine superano 450 pt, il testo viene inoltrato alla pagina successiva.

La mia domanda è: come posso ottenere lo spazio disponibile rimanente prima di scrivere un’immagine?

Per prima cosa: quando aggiungi testo e immagini a una pagina, iText a volte cambia l’ordine del contenuto testuale e dell’immagine. Puoi evitarlo usando:

writer.setStrictImageSequence(true); 

Se vuoi conoscere la posizione corrente del “cursore”, puoi usare il metodo getVerticalPosition() . Sfortunatamente, questo metodo non è molto elegante: richiede un parametro booleano che aggiungerà una nuova riga (se è true ) o ti darà la posizione sulla linea corrente (se false ).

Non capisco perché vuoi ottenere la posizione verticale. È perché vuoi avere una didascalia seguita da un’immagine e vuoi che la didascalia e l’immagine siano sulla stessa pagina?

In tal caso, puoi inserire il testo e le immagini all’interno di una cella di una tabella e istruire iText a non dividere le righe. In questo caso, iText inoltrerà sia il testo che l’immagine, nell’ordine corretto alla pagina successiva se il contenuto non si adatta alla pagina corrente.

Aggiornare:

Sulla base delle informazioni aggiuntive aggiunte nei commenti, è ora chiaro che l’OP vuole aggiungere immagini che sono filigranate.

Ci sono due approcci per raggiungere questo, a seconda del requisito reale.

Approccio 1:

Il primo approccio è spiegato nell’esempio WatermarkedImages1 . In questo esempio, creiamo un PdfTemplate al quale aggiungiamo un’immagine e del testo scritto sopra quell’immagine. Possiamo quindi avvolgere questo PdfTemplate all’interno di un’immagine e aggiungere quell’immagine insieme alla sua filigrana usando una singola istruzione document.add() .

Questo è il metodo che esegue tutta la magia:

 public Image getWatermarkedImage(PdfContentByte cb, Image img, String watermark) throws DocumentException { float width = img.getScaledWidth(); float height = img.getScaledHeight(); PdfTemplate template = cb.createTemplate(width, height); template.addImage(img, width, 0, 0, height, 0, 0); ColumnText.showTextAligned(template, Element.ALIGN_CENTER, new Phrase(watermark, FONT), width / 2, height / 2, 30); return Image.getInstance(template); } 

Ecco come aggiungiamo le immagini:

 PdfContentByte cb = writer.getDirectContentUnder(); document.add(getWatermarkedImage(cb, Image.getInstance(IMAGE1), "Bruno")); document.add(getWatermarkedImage(cb, Image.getInstance(IMAGE2), "Dog")); document.add(getWatermarkedImage(cb, Image.getInstance(IMAGE3), "Fox")); Image img = Image.getInstance(IMAGE4); img.scaleToFit(400, 700); document.add(getWatermarkedImage(cb, img, "Bruno and Ingeborg")); 

Come puoi vedere, abbiamo un’immagine molto grande (una foto di me e mia moglie). Abbiamo bisogno di ridimensionare questa immagine in modo che si adatti alla pagina. Se vuoi evitare questo, dai un’occhiata al secondo approccio.

Approccio 2:

Il secondo approccio è spiegato nell’esempio WatermarkedImages2 . In questo caso, aggiungiamo ogni immagine a un PdfPCell . Questo PdfPCell ridimensiona l’immagine in modo che si adatti alla larghezza della pagina. Per aggiungere la filigrana, utilizziamo un evento cella:

 class WatermarkedCell implements PdfPCellEvent { String watermark; public WatermarkedCell(String watermark) { this.watermark = watermark; } public void cellLayout(PdfPCell cell, Rectangle position, PdfContentByte[] canvases) { PdfContentByte canvas = canvases[PdfPTable.TEXTCANVAS]; ColumnText.showTextAligned(canvas, Element.ALIGN_CENTER, new Phrase(watermark, FONT), (position.getLeft() + position.getRight()) / 2, (position.getBottom() + position.getTop()) / 2, 30); } } 

Questo evento cella può essere utilizzato in questo modo:

 PdfPCell cell; cell = new PdfPCell(Image.getInstance(IMAGE1), true); cell.setCellEvent(new WatermarkedCell("Bruno")); table.addCell(cell); cell = new PdfPCell(Image.getInstance(IMAGE2), true); cell.setCellEvent(new WatermarkedCell("Dog")); table.addCell(cell); cell = new PdfPCell(Image.getInstance(IMAGE3), true); cell.setCellEvent(new WatermarkedCell("Fox")); table.addCell(cell); cell = new PdfPCell(Image.getInstance(IMAGE4), true); cell.setCellEvent(new WatermarkedCell("Bruno and Ingeborg")); table.addCell(cell); 

Utilizzerai questo approccio se tutte le immagini hanno più o meno le stesse dimensioni e se non vuoi preoccuparti di montare le immagini sulla pagina.

Considerazione:

Ovviamente, entrambi gli approcci hanno un risultato diverso a causa della scelta progettuale che è stata fatta. Si prega di confrontare i PDF risultanti per vedere la differenza: watermark_template.pdf versus watermark_table.pdf