Я получаю PDF-файлы с XHTML и летающей тарелкой. Я добавил изображения SVG (значки и т. Д.). Однако, когда я пытаюсь рисовать много изображений (например, 5000+), рендеринг занимает очень много времени (очевидно). Есть только 10 или около того различных изображений, которые нужно рисовать, но просто повторяя их много раз (одинаковый размер).Эффективный SVG-рендеринг для PDF-файлов (Java, Batik, Flying Saucer)
Есть ли способ/библиотека, чтобы сделать это эффективно?
В настоящее время используется батик, летающая тарелка комбо для рисования изображений. Следующий код используется для разбора 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 изображений занимают около 42 секунд на i5 8gb RAM.
Итак, есть способ сохранить нарисованный SVG в памяти и вставить его быстрее или что-то еще? Потому что прямо сейчас кажется, что все изображения являются отдельными изображениями и съедают всю мою память и уходят навсегда.