2009-01-02 138 views
10

我們使用iText從Java生成PDF(部分基於本網站的建議)。但是,將圖標的副本嵌入到GIF等圖像格式中會導致它在人物放大和縮小時看起來有點奇怪。iText中的矢量圖形PDF

理想情況下,我們希望將圖像嵌入矢量格式,如EPS,SVG或只是一個PDF模板。該網站聲稱,EPS支持已被刪除,在PDF中嵌入PDF或PS可能導致錯誤,甚至沒有提到SVG。

我們的代碼直接使用Graphics2D API而不是iText,但我們願意跳出AWT模式,並在達到結果時使用iText本身。如何才能做到這一點?

回答

8

按照documentation iText的支持以下圖片格式:JPEG,GIF,PNG,TIFF,BMP,WMF和EPS。我不知道這可能是任何幫助,但我已經成功地使用iTextSharp在PDF文件中嵌入矢量WMF圖像:

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

我得到一個異常,當我嘗試你的代碼,這不是爲我工作,我最近讀了eps不支持,你必須將其轉換爲WMF – Deumber 2012-02-12 21:00:37

3

我最近了解到,您可以將您的Graphics2D對象直接發送到iText,並且生成的PDF文件與可縮放矢量圖形一樣好。從你的帖子看來,這聽起來像是可以解決你的問題。

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

這就是我們已經在做的 - 使用Graphics2D繪製頁面。我們需要的是以矢量格式添加圖像。 – 2009-01-02 22:06:57

4

我發現一對夫婦的例子由iText的作者使用Graphics2D API和Apache Batik庫在PDF中繪製SVG。

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

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

對於我而言,我需要採取SVG的字符串並繪製在一個PDF在一定的大小和位置,同時保持圖像的載體性質(無光柵化) 。

我想繞過似乎盛行在SAXSVGDocumentFactory.createSVGDocument()函數中的SVG文件。我發現以下文章對使用SVG文本字符串而非平面文件很有幫助。

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

你必須創建你的字符串一個StringReader並傳遞到SAXSVGDocumentFactory#createDocument(字符串,閱讀器)方法。您作爲第一個參數傳遞給String的URI將成爲SVG文檔的基礎文檔URI。如果您的SVG引用任何外部文件,這應該是重要的。

最好的問候,

丹尼爾

Java源從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(); 

注意這將以此爲SVG到您正在使用的PDF。 SVG在文本上方顯示爲浮動圖層。我仍在努力移動/縮放它,並使其與文本保持一致,但希望這不在問題的直接範圍之內。

希望這能夠提供幫助。

乾杯

編輯:我能夠實現我的SVG使用如下的嵌入對象。註釋行用於添加快速邊框來檢查定位。

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

您好,我試圖找到一種方法來做類似的事情,以將SVG文件渲染爲PDF文檔。你使用哪種版本的Itext?我注意到構造函數對於類com.lowagie.text.pdf.PdfGraphics2D是私有的,至少在iText 2.1.2中,我無法在IText 5.5.4中找到這樣的類。謝謝! - Jose Tepedino 6分鐘前 – 2016-03-16 12:03:02

+0

@JoseTepedino對不起,我多年沒有碰過這個問題(因爲我寫了答案)。我會想象我使用的版本是在2012年9月左右發佈的,所以這可能是iText 5.3.2,它於2012年8月發佈,根據他們的GitHub版本 - https://github.com/itext/itextpdf/releases /tag/5.3.2。希望有所幫助。 – clayzermk1 2016-03-16 16:06:31

6

這是我從帖子,我發現這裏並正式實施例中導出:

/** 
* 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); 
} 

Image實例可以很容易地添加到PDF(在我的案件作爲簽名)。