6

How can I convert one WMF file to PNG/BMP/JPG format with custom output resolution?

Example: Take WMF file and outputs PNG file with 2000x2000 px.

Thanks in advance.

user1970058
  • 93
  • 1
  • 5
  • The only way to reliably convert this format is by using the Windows' GDI API, what is your operating system ? I've seen an online converter (zamzar.com) that seems to handle the format, but I'm not sure how well. – mmgp Jan 11 '13 at 13:33
  • Im using Ubuntu with Java 6 – user1970058 Jan 11 '13 at 13:40
  • Then you will need to luck, i.e., your WMF files are simple and don't use newer API calls from GDI(+). – mmgp Jan 11 '13 at 13:43

4 Answers4

5

You can use the excelent Batik ( http://xmlgraphics.apache.org/batik/ ) lib to achieve this. But you will need to follow this steps:

  1. Convert the WMF file to SVG using the WMFTranscoder
  2. Convert the SVG to JGP using the JPGTranscoder

WMF >> SVG >> JPG

Here is a discussion on coderanch about it: http://www.coderanch.com/t/422868/java/java/converting-WMF-Windows-Meta-File

Tiago
  • 2,871
  • 4
  • 23
  • 39
  • Interesting, does it guarantee that it always work even using a operating system different than Windows ? In that case, does it also fully support the newer WMF formats: EMF and EMF+ ? – mmgp Jan 11 '13 at 13:27
  • Ah, now I see a footnote on its page: "Windows Metafiles (WMF) are supported through classes in Apache Batik. At the moment, support for this format is experimental and may not always work as expected." – mmgp Jan 11 '13 at 13:31
  • @mmgp, yeah it works on Linux too, last year i did something like this and it works perfect. About the newer WMF format i dont know, i've only used the WMF exported by autocad. – Tiago Jan 11 '13 at 13:32
  • @mmgp, sometimes batik cant convert some objects and gives warnings, but this is best way that i can find to do this conversion... – Tiago Jan 11 '13 at 13:38
  • There is the `unoconv` tool which might be better, there is also libgdiplus from Mono which might be better too. – mmgp Jan 11 '13 at 13:40
2

WMF, EMF and EMF+ are integral parts of slideshows, therefore I've developed a renderer for those as part of Apache POI. As for the upcoming POI-4.1.2 this is still work in progress - if you have any rendering issues, please upload your file in a new bug report in our bugzilla.

The main description can be found in the POI documentation.

Here is an excerpt:

#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:

/* the file content */
InputStream is = ...;
/* Save and set System.in */
InputStream oldIn = System.in;
try {
    System.setIn(is);
    String[] args = {
        "-format", "png", // png,gif,jpg,svg or null for test
        "-outdir", new File("out/").getCanonicalPath(),
        "-outfile", "export.png",
        "-fixside", "long",
        "-scale", "800",
        "-ignoreParse",
        "stdin"
    };
    PPTX2PNG.main(args);
} finally {
    System.setIn(oldIn);
}

#2 - Render WMF / EMF / EMF+ via the *Picture classes

File f = samples.getFile("santa.wmf");
try (FileInputStream fis = new FileInputStream(f)) {
    // for WMF
    HwmfPicture wmf = new HwmfPicture(fis);
    // for EMF / EMF+
    HemfPicture emf = new HemfPicture(fis);
    Dimension dim = wmf.getSize();
    int width = Units.pointsToPixel(dim.getWidth());
    // keep aspect ratio for height
    int height = Units.pointsToPixel(dim.getHeight());
    double max = Math.max(width, height);
    if (max > 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"));
}
kiwiwings
  • 3,386
  • 1
  • 21
  • 57
  • 1
    This worked beautifully for me. Just as a note, I had to pull in the poi-scratchpad artifact (as opposed to just "poi") to get the classes under the org.apache.poi.hemf package. – Tim Russell Jul 17 '20 at 17:28
0

You can use different tools for this format. You can choose for example GIMP. In Java you have a library for converting WMF files.

Mihai8
  • 3,113
  • 1
  • 21
  • 31
0

I wrote a walkaround here, for Java I learned that I can run shell command following answers in this question. For WMF, convert it to EMF first following this answer.

Lerner Zhang
  • 6,184
  • 2
  • 49
  • 66