2009-01-02 7 views
10

Nous utilisons iText pour générer des PDF à partir de Java (en partie sur la base des recommandations de ce site). Cependant, l'intégration d'une copie de notre logo dans un format d'image comme le GIF donne un aspect un peu étrange à mesure que les gens zoome et descend.Graphismes vectoriels dans iText PDF

Idéalement, nous aimerions intégrer l'image dans un format vectoriel, tel que EPS, SVG ou simplement un modèle PDF. Le site web prétend que le support EPS a été abandonné, que l'intégration d'un fichier PDF ou PS dans un fichier PDF peut entraîner des erreurs et qu'il ne mentionne même pas SVG.

Notre code utilise l'API Graphics2D plutôt qu'iText directement, mais nous serions prêts à sortir du mode AWT et à utiliser iText lui-même s'il obtenait le résultat. Comment cela peut-il être fait?

Répondre

8

Selon le documentation iText prend en charge les formats d'image suivants: JPEG, GIF, PNG, TIFF, BMP, WMF et EPS. Je ne sais pas si cela pourrait être d'une aide, mais je l'ai utilisé avec succès iTextSharp pour intégrer vecteur WMF image dans un fichier pdf:

C#:

using System; 
using System.IO; 
using iTextSharp.text; 
using iTextSharp.text.pdf; 

public class Program 
{ 

    public static void Main() 
    { 
     Document document = new Document(); 
     using (Stream outputPdfStream = new FileStream("output.pdf", FileMode.Create, FileAccess.Write, FileShare.None)) 
     using (Stream imageStream = new FileStream("test.wmf", FileMode.Open, FileAccess.Read, FileShare.Read)) 
     { 
      PdfWriter.GetInstance(document, outputPdfStream); 
      Image wmf = Image.GetInstance(imageStream); 
      document.Open(); 
      document.Add(wmf); 
      document.Close(); 
     } 
    } 
} 
+1

Je reçois une exception quand j'ai essayé votre code, cela ne fonctionne pas pour moi, j'ai lu récemment que eps n'est pas supporté, vous devez le convertir en WMF – Deumber

3

J'ai récemment appris que vous pouvez envoyer votre objet Graphics2D directement à iText, et les fichiers PDF résultants sont tout aussi bons que les graphiques vectoriels évolutifs. De votre message, il semble que cela pourrait résoudre votre problème.

Document document = new Document(PageSize.LETTER); 
PdfWriter writer = null; 
try { 
    writer = PdfWriter.getInstance(document, new FileOutputStream(your file name)); 
} catch (Exception e) { 
    // do something with exception 
} 

document.open(); 

PdfContentByte cb = writer.getDirectContent(); 
PdfTemplate tp = cb.createTemplate(width, height); 
Graphics2D g2 = tp.createGraphics(width, height, new DefaultFontMapper()); 

// Create your graphics here - draw on the g2 Graphics object 

g2.dispose(); 
cb.addTemplate(tp, 0, 100); // 0, 100 = x,y positioning of graphics in PDF page 
document.close(); 
+0

C'est ce que nous faisons déjà - en utilisant Graphics2D pour dessiner à la page. Ce dont nous avons besoin est d'ajouter une image dans un format vectoriel. –

4

J'ai trouvé quelques exemples par le iText auteur qui utilisent l'API Graphics2D et la bibliothèque Apache Batik pour dessiner le SVG dans un fichier PDF.

http://itextpdf.com/examples/iia.php?id=269

http://itextpdf.com/examples/iia.php?id=263

Pour mes fins, je devais prendre une série de SVG et d'en tirer que dans un fichier PDF à une certaine taille et l'emplacement tout en maintenant la nature du vecteur de l'image (pas de pixellisation) . Je voulais contourner le fichier SVG qui semble prévalent dans les fonctions SAXSVGDocumentFactory.createSVGDocument(). J'ai trouvé le message suivant utile pour l'utilisation d'une chaîne de texte SVG au lieu d'un fichier plat.

http://batik.2283329.n4.nabble.com/Parse-SVG-from-String-td3539080.html

Vous devez créer un StringReader de votre chaîne et passez à la méthode que SAXSVGDocumentFactory # createDocument (String, Reader). L'URI que vous transmettez en tant que premier paramètre en tant que chaîne sera l'URI de document de base du document SVG. Cela ne devrait être important que si votre fichier SVG référence des fichiers externes.

Meilleures salutations,

Daniel

Java Source dérivées des exemples iText:

// SVG as a text string. 
String svg = "<svg>...</svg>"; 

// Create the PDF document. 
// rootPath is the present working directory path. 
Document document = new Document(); 
PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(new File(rootPath + "svg.pdf"))); 
document.open(); 

// Add paragraphs to the document... 
document.add(new Paragraph("Paragraph 1")); 
document.add(new Paragraph(" ")); 

// Boilerplate for drawing the SVG to the PDF. 
String parser = XMLResourceDescriptor.getXMLParserClassName(); 
SAXSVGDocumentFactory factory = new SAXSVGDocumentFactory(parser); 
UserAgent userAgent = new UserAgentAdapter(); 
DocumentLoader loader = new DocumentLoader(userAgent); 
BridgeContext ctx = new BridgeContext(userAgent, loader); 
ctx.setDynamicState(BridgeContext.DYNAMIC); 
GVTBuilder builder = new GVTBuilder(); 
PdfContentByte cb = writer.getDirectContent(); 

// Parse the SVG and draw it to the PDF. 
Graphics2D g2d = new PdfGraphics2D(cb, 725, 400); 
SVGDocument chart = factory.createSVGDocument(rootPath, new StringReader(svg)); 
GraphicsNode chartGfx = builder.build(ctx, chart); 
chartGfx.paint(g2d); 
g2d.dispose(); 

// Add paragraphs to the document... 
document.add(new Paragraph("Paragraph 2")); 
document.add(new Paragraph(" ")); 

document.close(); 

Notez que ce brossera un SVG au format PDF que vous travaillez. Le SVG apparaît comme un calque flottant au-dessus du texte. Je travaille toujours sur le déplacement/mise à l'échelle et le fait de rester en ligne avec le texte, mais j'espère que c'est en dehors de la portée immédiate de la question.

Espérons que cela a été en mesure d'aider.

Vive

EDIT: Je suis en mesure de mettre en œuvre mon svg comme un objet en ligne en utilisant ce qui suit. Les lignes commentées servent à ajouter une bordure rapide pour vérifier le positionnement.

SAXSVGDocumentFactory factory = new SAXSVGDocumentFactory(XMLResourceDescriptor.getXMLParserClassName()); 
UserAgent userAgent = new UserAgentAdapter(); 
DocumentLoader loader = new DocumentLoader(userAgent); 
BridgeContext ctx = new BridgeContext(userAgent, loader); 
ctx.setDynamicState(BridgeContext.DYNAMIC); 
GVTBuilder builder = new GVTBuilder(); 
SVGDocument svgDoc = factory.createSVGDocument(rootPath, new StringReader(svg)); 
PdfTemplate svgTempl = PdfTemplate.createTemplate(writer, Float.parseFloat(svgDoc.getDocumentElement().getAttribute("width")), Float.parseFloat(svgDoc.getDocumentElement().getAttribute("height"))); 
Graphics2D g2d = new PdfGraphics2D(svgTempl, svgTempl.getWidth(), svgTempl.getHeight()); 
GraphicsNode chartGfx = builder.build(ctx, svgDoc); 
chartGfx.paint(g2d); 
g2d.dispose(); 
Image svgImg = new ImgTemplate(svgTempl); 
svgImg.setAlignment(Image.ALIGN_CENTER); 
//svgImg.setBorder(Image.BOX); 
//svgImg.setBorderColor(new BaseColor(0xff, 0x00, 0x00)); 
//svgImg.setBorderWidth(1); 
document.add(svgImg); 
+1

Bonjour, J'essaie de trouver un moyen de faire quelque chose de similaire, rendre les fichiers SVG dans un document PDF. Quelle version d'Itext utilisez-vous? J'ai remarqué que les constructeurs sont privés pour la classe com.lowagie.text.pdf.PdfGraphics2D, au moins dans iText 2.1.2, et je n'ai pas pu trouver une telle classe dans IText 5.5.4. Merci! - Jose Tepedino 6 mins ago –

+0

@JoseTepedino Je suis désolé, mais je n'ai pas touché cela depuis des années (depuis que j'ai écrit la réponse). J'imagine que j'utilisais une version sortie vers septembre 2012, donc ce serait probablement iText 5.3.2 qui a été publié en août 2012 d'après leurs versions de GitHub - https://github.com/itext/itextpdf/releases /tag/5.3.2. J'espère que cela pourra aider. – clayzermk1

+0

merci pour votre message! J'ai fait un petit progrès, en trouvant une page API indiquant que la classe PdfGraphics2D du paquet com.itextpdf.awt existe depuis iText 5.0.2: http://developers.itextpdf.com/reference/com.itextpdf.awt.PdfGraphics2D . J'ai encore du terrain à couvrir, mais trouver la bonne version à utiliser est un bon début. Merci! –

6

Ce que je tirais des postes que je trouve ici et les exemples officiels:

/** 
* Reads an SVG Image file into an com.itextpdf.text.Image instance to embed it into a PDF 
* @param svgPath SVG filepath 
* @param writer PdfWriter instance 
* @return Instance of com.itextpdf.text.Image holding the SVG file 
* @throws IOException 
* @throws BadElementException 
*/ 
private static Image getSVGImage(String svgPath, PdfWriter writer) throws IOException, BadElementException { 
    SVGDocument svgDoc = new SAXSVGDocumentFactory(null).createSVGDocument(null, new FileReader(svgPath)); 

    // Try to read embedded height and width 
    float svgWidth = Float.parseFloat(svgDoc.getDocumentElement().getAttribute("width").replaceAll("[^0-9.,]","")); 
    float svgHeight = Float.parseFloat(svgDoc.getDocumentElement().getAttribute("height").replaceAll("[^0-9.,]","")); 

    PdfTemplate svgTempl = PdfTemplate.createTemplate(writer, svgWidth, svgHeight); 
    Graphics2D g2d = new PdfGraphics2D(svgTempl, svgTempl.getWidth(), svgTempl.getHeight()); 
    GraphicsNode chartGfx = (new GVTBuilder()).build(new BridgeContext(new UserAgentAdapter()), svgDoc); 
    chartGfx.paint(g2d); 
    g2d.dispose(); 

    return new ImgTemplate(svgTempl); 
} 

L'instance d'image peut l'être ajouté facilement au format pdf (dans mon cas comme une signature).

+1

Les classes de code ci-dessus peuvent être importés en utilisant la dépendance suivante maven: ' org.apache.xmlgraphics batik-gvt 1,7' –

Questions connexes