Agregar Imagenes a documentos Pdf con iText

Otra de las posibilidades que proporciona la librería iText es agregar imágenes a los documentos pdf que nuestra aplicación o sistema vayan a generar, algo por demás útil, ya sea para agregar imágenes e ilustraciones o para generar un membrete personalizado.

Lo mejor del caso es lo bastante sencillo que es realizar esto, no es necesario ningún tipo de pre-conversión, paso a mapa de bit binario ni cosas por el estilo, basta que tenga la imagen a la mano.

Como en entradas anteriores la forma de hacer esto se explicara con un ejemplo, del cual se comentaran a detalle las lineas claves, su significado e implicaciones, antes de comenzar necesita preparar un proyecto en Java el cual incluya la libreria iText, si esta utilizando el entorno Eclipse y no sabe como hacer esto puedo recomendar una entrada anterior de este blog, donde se describe el proceso a detalle: iText, Generación de archivo Pdf en Java, ya que este listo el proyecto podemos comenzar.

Figura 1 - Proyecto con iText
Figura 1 – Proyecto con iText

Antes de comenzar debe recordar un detalle importante sobre la forma en que Eclipse ejecuta los programas (esto es si usa el botón ejecutar del entorno), los programas se ejecutan en el directorio raíz del proyecto, de modo que si no planea poner una ruta absoluta a la imagen, lo mas sencillo, y similar al ejemplo que se manejara es ubicar la imagen en el directorio raíz del proyecto, como se ve en la figura 2.

Figura 2 - Directorio Raíz del proyecto
Figura 2 – Directorio Raíz del proyecto

La clase Image.

He aquí el código que usaremos como ejemplo, con énfasis en las lineas mas relevantes, este generara un documento de tres paginas, mostrando detalles sobre posicionamiento y alineación de la imagen, como las figuras mostraran:

package mx.com.hashSoft;

import java.io.FileOutputStream;
import java.io.IOException;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Element;
import com.itextpdf.text.Image;
import com.itextpdf.text.PageSize;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.pdf.PdfWriter;

public class Imagen {
    
    /**
     * Crea un documento con encabezado y conteo de
     * paginas, para este ejemplo se crean 100 paginas
     * @param filename Nombre del archivo
     */
    public void createPdf(String filename) throws IOException, DocumentException
    {        
        Document document = new Document(PageSize.LETTER , 36, 36, 54, 36);
        Paragraph parrafo, parrafo2, parrafo3;
        Image imagen = Image.getInstance(“hash_avatar.png”);       
        
        PdfWriter.getInstance(document, new FileOutputStream(“Image.pdf”));

        document.open();
        
        //Creamos una cantidad significativa de paginas para probar el encabezado
        parrafo = new Paragraph(“Esta es una de las paginas de prueba de nuestro programa, Vemos que la imagen queda *despues* de este texto.”);
        parrafo.setAlignment(Element.ALIGN_CENTER);

        imagen.setAlignment(Element.ALIGN_CENTER);

        document.add(parrafo);
        document.add(imagen);
        
        document.newPage();
        parrafo2 = new Paragraph(“En esta pagina estamos usando posicionamiento absoluto, por lo que el texto queda encima de la imagen”);
        
        imagen.setAbsolutePosition(150f, 650f);
        document.add(imagen);
        document.add(parrafo2);    
        
        document.newPage();
        parrafo3 = new Paragraph(“Aqui podemos observar el origen del sistema de cordenadas que iText usa para los posicionamientos absolutos”);
        imagen.setAbsolutePosition(0f, 0f);

        document.add(imagen);
        document.add(parrafo3);       
        document.close();        
    }

    static public void main(String[] args)
    {
        Imagen doc = new Imagen();
        
        try{
            // Creamos el documento Pdf
            doc.createPdf(“documento.pdf”);
            
        }catch(DocumentException ed)
        {
            System.err.println(“Error al crear el documento Pdf”);
        }
        catch(IOException ex)
        {
            System.err.println(“Error General de Entrada/Salida”);
        }
    }   
}

Notara que se creo un objecto Image por medio del método getInstance de la forma:

Image imagen = Image.getInstance(“hash_avatar.png”);  

Esta es la función clave aquí, pues con ella le indicamos al programa que deseamos crear una referencia a la imagen en la ruta indicada como argumento de modo que podemos agregar esa imagen a nuestro documento con solo usar el método add del objecto Document, como muestra la linea.

document.add(imagen);

Y listo solo con eso ya tendrá una imagen agregada a su documento, algo que destacar es que, de igual modo que los párrafos, puede indicar la alineación que desea tenga la imagen, ya sea a la izquierda, centrado o a la derecha por medio del método setAlignment, como se ve en la linea, en la Figura 3 puede observar el resultado de usar imagen.setAlignment(Element.ALIGN_CENTER);

Figura 3 - Usando etAlignment(Element.ALIGN_CENTER)
Figura 3 – Usando etAlignment(Element.ALIGN_CENTER)

Posicionamiento manual

También podría ser deseable indicar con precisión donde desea que aparezca la imagen e incluso que no siga el orden de los demás elementos del documento e incluso halla empalmes con estos, esto también puede lograrse por medio del método setAbsolutePosition como se ve en la linea:

imagen.setAbsolutePosition(150f, 650f);

Esta nos permite indicar la posición en pixeles, como podrá ver en la Figura 4

Figura 4 - Posicionamiento manual
Figura 4 – Posicionamiento manual

Cuando se trata del posicionamiento manual iText maneja un sistema de coordenadas cuyo origen se ubica en la esquina inferior izquierda del documento, esto se ejemplifica con la linea

imagen.setAbsolutePosition(0f, 0f);

La cual coloca la imagen en la posición mostrada en la figura 5

Figura 5 - Origen de las coordenadas
Figura 5 – Origen de las coordenadas

Y claro esto es solo una pequeña parte de las posibilidades proporcionadas por la librería iText (Tambien es posible generar transparencias y rotar la imagen), por lo pronto esto sera todo, espero que la entrada halla sido de utilidad y nos vemos pronto.

Referencias

Java IText: Image – http://tutorials.jenkov.com/java-itext/image.html

Anuncios

18 comentarios sobre “Agregar Imagenes a documentos Pdf con iText

    1. Para eso deber usar los eventos de pagina, esos se detallan en esta entrada: https://hashblogeando.wordpress.com/2013/09/24/agregando-un-membrete-a-un-documento-pdf-con-itext/ ,esta linea table.writeSelectedRows(0, -1, 140f, 700f, writer.getDirectContent()); es donde pones la imagen y como se nota puedes indicar la posicion absoluta, te recomiendo le des una leida a la entrada y experimentes un poco, las imágenes pueden hacerse translucidas, pero no recuerdo la función exacta en este momento.

  1. buenas buenas, ando justamente buscando algo parecido, mi duda es como hacer para hacer la diferencia entre el encabezado y ya el cuerpo del archivo, ya que hasta el momento se escriben en la misma linea

  2. Hola, ayuda porfa, tengo un inconveniente, al transformar un archivo de axcel a pdf manualmente y mediante mi programa agregar una imagen y texto los datos no se muestran, como puedo hacer para que la misma si se vea?

    Actualmente la parte de código en donde se añaden los datos es la siguiente.

    for(int j=0; j<numMaxPages; j++)
    {
    Rectangle pageSize = reader.getPageSize(j+1);
    float width = pageSize.getWidth();
    float height = pageSize.getHeight();
    PdfContentByte canvas = stp.getOverContent(j+1);
    ColumnText.showTextAligned(canvas, Element.ALIGN_LEFT, new Phrase(feetPage, FontFactory.getFont(FontFactory.HELVETICA, 10, Font.BOLDITALIC)), width – 278, height – 52, 0);

    Image image = Image.getInstance(CodeQRService.generateCode(textoQR), null);
    image.setAbsolutePosition(width – 85, height – 107);
    canvas.addImage(image);
    PdfContentByte canvasDate = stp.getOverContent(j+1);
    ColumnText.showTextAligned(canvasDate, Element.ALIGN_LEFT, new Phrase(strDate, FontFactory.getFont(FontFactory.HELVETICA, 10, Font.BOLDITALIC)), width – 278, height – 62, 0);
    }

    Gracias.

    1. Una duda, ¿Estas creando el documento desde cero o modificando un documento ya existente?, esto lo pregunto por el uso de PdfContentByte para lo que parece es acceder al contenido, la forma en que he hecho documentos similares es vía la clase Document para ir agregando y formateando el contenido según se cree, un ejemplo sencillo de esto que hace lo que necesitas, crear una tabla y luego agregar un código QR en una posición fija lo puedes encontras aquí:

      https://gitlab.com/ticomWebcomic/TablaPlusImagen/blob/master/src/main/java/mx/hash/fontsize/tablaplusimagen/Tablas.java

      Es un ejemplo muy simple, pero espero pueda servirte de base para crear el documento que necesitas.

      Saludos.

  3. hola que tal salados muy gran aporte me saco de un gran apuro hace dos meses ya que en mi trabajo me toca hacer todo lo relacionado con reportes en pdf y alli fue un gran logro tu tutorial ahora tengo una nueva problematica deseo de un archivo pdf generado anteriormente colocar una imagen o una firma digital tengo un codigo pero no puedo despejar el error ayuda import java.security.*;
    import java.security.cert.Certificate;
    import java.io.*;

    import com.itextpdf.text.Rectangle;
    import com.itextpdf.text.pdf.PdfReader;
    import com.itextpdf.text.pdf.PdfSignatureAppearance;
    import com.itextpdf.text.pdf.PdfSignatureAppearance.RenderingMode;
    import com.itextpdf.text.pdf.PdfStamper;
    import com.itextpdf.text.pdf.security.BouncyCastleDigest;
    import com.itextpdf.text.pdf.security.ExternalDigest;
    import com.itextpdf.text.pdf.security.ExternalSignature;
    import com.itextpdf.text.pdf.security.MakeSignature;
    import com.itextpdf.text.pdf.security.MakeSignature.CryptoStandard;
    import com.itextpdf.text.pdf.security.PrivateKeySignature;

    public class FirmarPDF {

    public static void signPDF(String inputFileName, String outputFileName, String keystorePath, String keystorePassword) {
    try {
    //
    // if (args.length == 0) {
    // System.out.print(“Nombre de PDF a firmar”);
    // System.exit(1);
    // }
    char[] charArrayKeystorePassword = keystorePassword.toCharArray();
    KeyStore ks = KeyStore.getInstance(“pkcs12”, “BC”);
    ks.load(new FileInputStream(keystorePath), charArrayKeystorePassword);

    String alias = (String)ks.aliases().nextElement();
    PrivateKey key = (PrivateKey)ks.getKey(alias, charArrayKeystorePassword);
    Certificate[] chain = ks.getCertificateChain(alias);

    PdfReader reader = new PdfReader(inputFileName);
    FileOutputStream fout = new FileOutputStream(outputFileName);

    PdfStamper stp = PdfStamper.createSignature(reader, fout, ‘\0’);

    PdfSignatureAppearance sap = stp.getSignatureAppearance();

    sap.setReason(“firma de prueba”);
    sap.setLocation(“qwewqeqe321”);
    sap.setCertificationLevel(PdfSignatureAppearance.CERTIFIED_NO_CHANGES_ALLOWED);
    sap.setRenderingMode(RenderingMode.DESCRIPTION);
    // Comentar la siguiente línea para no hacer visible la firma
    sap.setVisibleSignature(new Rectangle(400, 510, 500, 560), 1, null);

    ExternalSignature es = new PrivateKeySignature(key, “SHA-256”, “BC”);
    ExternalDigest digest = new BouncyCastleDigest();
    MakeSignature.signDetached(sap, digest, es, chain, null, null, null, 0, CryptoStandard.CMS);

    } catch (Exception e) {
    e.printStackTrace();
    }

    }
    }

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión /  Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión /  Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión /  Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión /  Cambiar )

Conectando a %s