performance - Efficient SVG rendering for PDFs (Java, Batik, Flying Saucer) -
i'm rendering pdfs xhtml , flying saucer. i've added svg images (icons etc) well. however, when try draw lot of images (like 5000+) rendering takes long (obviously). there 10 or different images draw, repeating them lot of times (same size).
is there way/library efficiently?
currently using batik, flying saucer combo draw images. following code used parse xhtml , find img tags place svg images:
@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); }
and draw images use:
@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); }
an idea of scaling. 100 images take 2 seconds, 5000 images take 42 seconds on i5 8gb ram.
so there way store drawn svg in memory , paste more or something? because right seems take images separate images , eat memory , take forever.
managed optimize memory , speed doing 2 things. pre-generated svgdocuments in createreplacedelement
method sped bit. main improvement pre-generating pdftemplates images. increased speed templates contained rendered images. rendering of regular text still slow, might turn down dpi.
edit: further optimization see is there way improve performance of flyingsaucer?
Comments
Post a Comment