Rendering slideshows, WMF, EMF and EMF+
Please be aware, that the documentation on this page reflects the current development, which might not have been released. If you rely on an unreleased feature, either use a nightly development build or feel free to ask on the mailing list for the release schedule.
Rendering slideshows, WMF, EMF and EMF+

For rendering slideshow (HSLF/XSLF), WMF, EMF and EMF+ pictures, POI provides an utility class PPTX2PNG:

Options: -scale scale factor -fixSide specify side (long,short,width,height) to fix - use as amount of pixels -slide 1-based index of a slide to render -format png,gif,jpg,svg,pdf (log,null for testing) -outdir output directory, defaults to origin of the ppt/pptx file -outfile output filename, defaults to "${basename}-${slideno}.${format}" -outpat output filename pattern, defaults to "${basename}-${slideno}.${format}" patterns: basename, slideno, format, ext -dump dump the annotated records to a file -quiet do not write to console (for normal processing) -ignoreParse ignore parsing error and continue with the records read until the error -extractEmbedded extract embedded parts -inputType default input file type (OLE2,WMF,EMF), default is OLE2 = Powerpoint some files (usually wmf) don't have a header, i.e. an identifiable file magic -textAsShapes text elements are saved as shapes in SVG, necessary for variable spacing often found in math formulas -charset sets the default charset to be used, defaults to Windows-1252 -emfHeaderBounds force the usage of the emf header bounds to calculate the bounding box -fontdir (PDF only) font directories separated by ";" - use $HOME for current users home dir defaults to the usual plattform directories -fontTtf (PDF only) regex to match the .ttf filenames -fontMap ";"-separated list of font mappings : ]]>
Instructions to run

Download the current nightly and for SVG/PDF the additional dependencies.

Execute the java command (Unix-paths needs to be replaced for Windows - use "-charset" for non-western WMF/EMFs):

java -cp poi-5.4.1.jar:poi-ooxml-5.4.1.jar:poi-ooxml-lite-5.4.1.jar:poi-scratchpad-5.4.1.jar:lib/*:ooxml-lib/*:auxiliary/* org.apache.poi.xslf.util.PPTX2PNG -format png -fixside long -scale 1000 -charset GBK file.pptx

If you want to use the renderer on the module path (JPMS) there a currently a few more steps necessary:

  • Create a build project using Maven, Gradle or your favorite build tool.
  • Alternatively, download the jars from https://repo1.maven.org/maven2/org/apache/poi/
  • Exclude poi-ooxml-full-5.4.1.jar,poi-javadoc-5.4.1.jar and auxiliary/xml-apis-1.4.01.jar (Java 11+) into new subdirectory "unused"
  • Move all other jars in current directory into a new subdirectory "poi"
  • Invoke PPTX2PNG: java --module-path poi:lib:auxiliary:ooxml-lib --module org.apache.poi.ooxml/org.apache.poi.xslf.util.PPTX2PNG -format png -fixside long -scale 1000 file.pptx
JDK 1.8 is by default using the PiscesRenderingEngine and affected by Busy loop hangs. To workaround this, use the MarlinRenderingEngine which is experimental provided starting from openjdk8u252 (JDK-8143849) via -Dsun.java2d.renderer=sun.java2d.marlin.MarlinRenderingEngine or for older jdk builds, preload the marlin jar.
Integrate rendering in your code
#1 - Use PPTX2PNG via file or stdin

For file system access, you need to save your slideshow/WMF/EMF/EMF+ first to disc and then call PPTX2PNG.main() with the corresponding parameters.

for stdin access, you need to redirect System.in before:

#2 - Render WMF / EMF / EMF+ via the *Picture classes 1500) { width *= 1500/max; height *= 1500/max; } BufferedImage bufImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); Graphics2D g = bufImg.createGraphics(); g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC); g.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON); wmf.draw(g, new Rectangle2D.Double(0,0,width,height)); g.dispose(); ImageIO.write(bufImg, "PNG", new File("bla.png")); } ]]>
#3 - Render slideshows directly ss = SlideShowFactory.create(file, null, true)) { Dimension pgsize = ss.getPageSize(); int width = (int) (pgsize.width * scale); int height = (int) (pgsize.height * scale); for (Slide slide : ss.getSlides()) { BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); Graphics2D graphics = img.createGraphics(); // default rendering options graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); graphics.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); graphics.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC); graphics.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON); graphics.setRenderingHint(Drawable.BUFFERED_IMAGE, new WeakReference<>(img)); graphics.scale(scale, scale); // draw stuff slide.draw(graphics); ImageIO.write(img, "PNG", new File("output.png")); graphics.dispose(); img.flush(); } } ]]>