PDFS(Java,Batik,Flying Saucer)的有效SVG渲染



我正在用XHTML和飞碟渲染PDF。我还添加了SVG图像(图标等)。但是,当我尝试绘制大量图像(例如5000 )时,渲染需要很长时间(显然)。只有10张左右的图像可以绘制,但只重复了很多次(相同的大小)。

有没有办法/库有效地执行此操作?

当前使用蜡染,飞碟组合绘制图像。以下代码用于解析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 RAM上大约需要42秒。

因此,是否可以将绘制的SVG存储在内存中并更快地粘贴它?因为现在似乎将所有图像视为单独的图像,并吞噬我所有的记忆并永远占据。

通过做两件事来设法优化内存和速度。我在createReplacedElement方法中预先生成了SVGDOCUMENTS,该方法将其加速了一点。主要的改进是预先生成所有图像的所有PDFTEMPLES。由于模板已经包含渲染图像,因此这种速度大大提高。所有常规文本的渲染仍然很慢,因此我可能会拒绝DPI。

编辑:进一步的优化请参见有任何方法改善蝇林的性能?

最新更新