2015-05-12 65 views
2

我使用XHTML和飛碟渲染PDF。我還添加了SVG圖像(圖標等)。但是,當我嘗試繪製大量圖像(如5000+)時,渲染需要很長時間(顯然)。只有10種不同的圖像可以繪製,但只是重複它們很多次(相同的大小)。PDF的高效SVG渲染(Java,蠟染,飛碟)

有沒有一種方法/庫有效地做到這一點?

目前使用蠟染,飛碟組合繪製圖像。下面的代碼是用來解析XHTML和找到的img標籤放置SVG圖像:

@Override 
public ReplacedElement createReplacedElement(LayoutContext layoutContext, BlockBox blockBox, UserAgentCallback userAgentCallback, int cssWidth, int cssHeight) { 
    Element element = blockBox.getElement(); 
    if (element == null) { 
     return null; 
    } 
    String nodeName = element.getNodeName(); 
    if ("img".equals(nodeName)) { 
     SAXSVGDocumentFactory factory = new SAXSVGDocumentFactory(XMLResourceDescriptor.getXMLParserClassName()); 
     SVGDocument svgImage = null; 
     try { 
      svgImage = factory.createSVGDocument(new File(element.getAttribute("src")).toURL().toString()); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
     Element svgElement = svgImage.getDocumentElement(); 
     element.appendChild(element.getOwnerDocument().importNode(svgElement, true)); 
     return new SVGReplacedElement(svgImage, cssWidth, cssHeight); 
    } 
    return this.superFactory.createReplacedElement(layoutContext, blockBox, userAgentCallback, cssWidth, cssHeight); 
} 

,並提請我使用的圖像:

@Override 
public void paint(RenderingContext renderingContext, ITextOutputDevice outputDevice, 
     BlockBox blockBox) { 

    PdfContentByte cb = outputDevice.getWriter().getDirectContent(); 
    float width = cssWidth/outputDevice.getDotsPerPoint(); 
    float height = cssHeight/outputDevice.getDotsPerPoint(); 

    PdfTemplate template = cb.createTemplate(width, height); 
    Graphics2D g2d = template.createGraphics(width, height); 
    PrintTranscoder prm = new PrintTranscoder(); 
    TranscoderInput ti = new TranscoderInput(svg); 
    prm.transcode(ti, null); 
    PageFormat pg = new PageFormat(); 
    Paper pp = new Paper(); 
    pp.setSize(width, height); 
    pp.setImageableArea(0, 0, width, height); 
    pg.setPaper(pp); 
    prm.print(g2d, pg, 0); 
    g2d.dispose(); 

    PageBox page = renderingContext.getPage(); 
    float x = blockBox.getAbsX() + page.getMarginBorderPadding(renderingContext, CalculatedStyle.LEFT); 
    float y = (page.getBottom() - (blockBox.getAbsY() + cssHeight)) + page.getMarginBorderPadding(
      renderingContext, CalculatedStyle.BOTTOM); 
    x /= outputDevice.getDotsPerPoint(); 
    y /= outputDevice.getDotsPerPoint(); 

    cb.addTemplate(template, x, y); 
} 

比例的想法。 100張圖像需要2秒鐘,5000張圖像在i5 8GB內存上需要約42秒。

那麼有沒有一種方法可以將繪製的SVG存儲在內存中並更快地粘貼它?因爲現在它似乎把所有圖像作爲單獨的圖像,並把我所有的記憶永久記錄下來。

回答

1

管理通過做兩件事來優化內存和速度。 我在createReplacedElement方法中預先生成了SVGDocuments,這個方法加快了它的速度。 主要改進是爲所有圖像預生成所有pdfTemplates。由於模板已包含渲染圖像,因此速度大大提高。 所有普通文本的渲染速度仍然很慢,所以我可能會拒絕DPI。

編輯:進一步優化見Is there any way improve the performance of FlyingSaucer?