http://stackoverflow.com/questions/408042/vector-graphics-in-itext-pdf
3 down vote
|
I found a couple of examples by the iText author that use the Graphics2D API and the Apache Batik library to draw the SVG in a PDF.
http://itextpdf.com/examples/iia.php?id=269
http://itextpdf.com/examples/iia.php?id=263
For my purposes, I needed to take a string of SVG and draw that in a PDF at a certain size and location while maintaining the vector nature of the image (no rasterization).
I wanted to bypass the SVG file that seems prevalent in the SAXSVGDocumentFactory.createSVGDocument() functions. I found the following post helpful for using a SVG text string instead of a flat file.
http://batik.2283329.n4.nabble.com/Parse-SVG-from-String-td3539080.html
You have to create a StringReader from your String and pass that to the SAXSVGDocumentFactory#createDocument(String, Reader) method. The URI that you pass as the first parameter as a String will be the base document URI of the SVG document. This should only be important if your SVG references any external files.
Best regards,
Daniel
Java Source derived from the iText examples:
|
Java Source derived from the iText examples:
// SVG as a text string.String svg ="<svg>...</svg>";// Create the PDF document.// rootPath is the present working directory path.Document document =newDocument();PdfWriter writer =PdfWriter.getInstance(document,newFileOutputStream(newFile(rootPath +"svg.pdf")));document.open();// Add paragraphs to the document...document.add(newParagraph("Paragraph 1"));document.add(newParagraph(" "));// Boilerplate for drawing the SVG to the PDF.String parser =XMLResourceDescriptor.getXMLParserClassName();SAXSVGDocumentFactory factory =newSAXSVGDocumentFactory(parser);UserAgent userAgent =newUserAgentAdapter();DocumentLoader loader =newDocumentLoader(userAgent);BridgeContext ctx =newBridgeContext(userAgent, loader);ctx.setDynamicState(BridgeContext.DYNAMIC);GVTBuilder builder =newGVTBuilder();PdfContentByte cb = writer.getDirectContent();// Parse the SVG and draw it to the PDF.Graphics2D g2d =newPdfGraphics2D(cb,725,400);SVGDocument chart = factory.createSVGDocument(rootPath,newStringReader(svg));GraphicsNode chartGfx = builder.build(ctx, chart);chartGfx.paint(g2d);g2d.dispose();// Add paragraphs to the document...document.add(newParagraph("Paragraph 2"));document.add(newParagraph(" "));document.close();
Note that this will draw a SVG to the PDF you are working on. The SVG appears as a floating layer above text. I'm still working on moving/scaling it and having it rest inline with text, but hopefully that is outside the immediate scope of the question.
Hope this was able to help.
Cheers
EDIT: I was able to implement my svg as an inline object using the following. The commented lines are for adding a quick border to check positioning.
SAXSVGDocumentFactory factory =newSAXSVGDocumentFactory(XMLResourceDescriptor.getXMLParserClassName());UserAgent userAgent =newUserAgentAdapter();DocumentLoader loader =newDocumentLoader(userAgent);BridgeContext ctx =newBridgeContext(userAgent, loader);ctx.setDynamicState(BridgeContext.DYNAMIC);GVTBuilder builder =newGVTBuilder();SVGDocument svgDoc = factory.createSVGDocument(rootPath,newStringReader(svg));PdfTemplate svgTempl =PdfTemplate.createTemplate(writer,Float.parseFloat(svgDoc.getDocumentElement().getAttribute("width")),Float.parseFloat(svgDoc.getDocumentElement().getAttribute("height")));Graphics2D g2d =newPdfGraphics2D(svgTempl, svgTempl.getWidth(), svgTempl.getHeight());GraphicsNode chartGfx = builder.build(ctx, svgDoc);chartGfx.paint(g2d);g2d.dispose();Image svgImg =newImgTemplate(svgTempl);svgImg.setAlignment(Image.ALIGN_CENTER);//svgImg.setBorder(Image.BOX);//svgImg.setBorderColor(new BaseColor(0xff, 0x00, 0x00));//svgImg.setBorderWidth(1);document.add(svgImg);
简单的代码:
Document document =newDocument(PageSize.LETTER);
PdfWriter writer =null;
try{
writer =PdfWriter.getInstance(document,newFileOutputStream(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,newDefaultFontMapper());
// 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();
官方例子:
/** * 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 staticImage getSVGImage(String svgPath,PdfWriter writer)
throwsIOException,BadElementException{
SVGDocument svgDoc =newSAXSVGDocumentFactory(null).createSVGDocument(null,newFileReader(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 =newPdfGraphics2D(svgTempl, svgTempl.getWidth(), svgTempl.getHeight());
GraphicsNode chartGfx =(newGVTBuilder()).build(newBridgeContext(newUserAgentAdapter()), svgDoc);
chartGfx.paint(g2d);
g2d.dispose();
returnnewImgTemplate(svgTempl);
}
|
edited
Sep 26 '12 at 0:14
|
answered
Sep 19 '12 at 21:10
|