2015-05-12 45 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?