我们如何使用任何Java API将WMF/EMF(MS元文件)转换为标准图像,如JPG或PNG?

问题描述:

我一直坚持使用Java将WMF/EMF图像转换为标准图像格式,如JPG或PNG。我们如何使用任何Java API将WMF/EMF(MS元文件)转换为标准图像,如JPG或PNG?

什么是最好的选择?

+3

产生WMF/EMF图像的人应该被枪杀,但它的价值在于:我确信美妙的(和免费的)* ImageMagick *曾经能够转换WMF文件。也曾经是ImageMagick的Java包装(如果内存服务,称为JMagick)。所以你可能想看看那里。这就是说我记得WMF/EMF只是各种格式的“炮弹”或“包装器”,所以它可能是一个移动的目标,并且很可能有很多不同的WMF/EMF文件,而我我真的不确定这是否仍然正确处理。它曾经工作,说...... – SyntaxT3rr0r

这是一种方法。

  1. 获取(或制作)可呈现相关文件的Java组件。
  2. 创建与组件需要显示图像相同尺寸的BufferedImage
  3. BufferedImage获取Graphics对象。
  4. 致电renderComponent.paintComponent(Graphics)
  5. 使用ImageIO.write()变体之一保存图像。

请参阅我对Swing: Obtain Image of JFrame的回答,以获取步骤2-5。第一步是我要问Google的。

+0

可以告诉我一段代码..所以我可以理解..我无法创建一个图像(java.awt.Image)出有问题的文件。这再次引发了创建BufferedImage的问题。希望你明白。 – pinkb

Batik library是一个工具包,用于处理Java中的SVG。有像WMFTranscoder这样的转换器将WMF转换为SVG,JPEGTranscoderPNGTranscoder将SVG转换为JPEG/PNG。有关更多详情,请参阅Transcoder API Docs

另一种选择是ImageMagick。它不是Java,但具有Java绑定:im4javaJMagick

wmf是矢量文件格式。为获得最佳效果,请将它们转换为.svg.pdf格式。 我做到了在两个阶段

1)wmf2fig --auto XXXX.wmf

2)fig2pdf --nogv XXXX.fig

我创建一个Python脚本批量转换

import subprocess as sbp 
a = sbp.Popen("ls *.wmf",shell=True, stderr=sbp.PIPE, stdout=sbp.PIPE) 
filelist = a.communicate()[0].splitlines() 

for ele in filelist: 
    cmdarg = 'wmf2fig --auto '+ ele.rsplit('.',1)[0]+'.wmf' 
    a = sbp.Popen(cmdarg, shell=True, stderr=sbp.PIPE, stdout=sbp.PIPE) 
    out = a.communicate() 

for ele in filelist: 
    cmdarg = 'fig2pdf --nogv '+ ele.rsplit('.',1)[0]+'.fig' 
    a = sbp.Popen(cmdarg, shell=True, stderr=sbp.PIPE, stdout=sbp.PIPE) 
    out = a.communicate() 

cmdarg = 'rm *.fig' 
a = sbp.Popen(cmdarg, shell=True, stderr=sbp.PIPE, stdout=sbp.PIPE) 
out = a.communicate() 
+0

尽管答案并不是关于Java,但我同意最好将转换后的结果保留为向量。 Batik将能够转换为SVG。 – haraldK

我前段时间创建了一些蜡染包装的包装(如vanje's answer所述),该包装为SGV和WMF/EMF提供ImageIO支持。

有了这些插件,你应该能够编写:

ImageIO.write(ImageIO.read(wmfFile), pngFile, "png"); 

的源代码上GitHub

虽然ImageIO插件很方便,但im4java和JMagick可能仍然有更好的格式支持。

如果您在Windows环境中部署应用程序,则SWT可以为您处理转换。

Image image = new Image(Display.getCurrent(), "test.wmf");     
    ImageLoader loader = new ImageLoader(); 
    loader.data = new ImageData[] { image.getImageData() }; 
    try(FileOutputStream stream = new FileOutputStream("test.png")) 
    { 
     loader.save(stream, SWT.IMAGE_PNG); 
    } 
    image.dispose(); 

SWT的目的是提供围绕本地功能的Java包装,在这种情况下,它调用Windows GDI直接得到它呈现WMF。