转换EMF/WMF文件到PNG/JPG



我正在接收一个Word docx文档的表单上传。我成功地完成了所有解析。然后我必须在网页上显示那个Word文档。

我现在遇到的问题是,我已经嵌入了EMF文件(PIL库识别为WMF格式),我不知道如何将它们转换为可以在网络上显示的东西(任意选择的PNG)。

代码比较简单:

im = PIL.Image.open(StringIO.StringIO(data))
fmt = im.format
if (fmt == 'WMF'):
  fmt = 'PNG'
  output = StringIO.StringIO()
  im.save(output, format=fmt)
  data = output.getvalue()
  output.close()
return '''<img src="data:image/{0};base64,{1}" />'''.format(fmt, base64.encodestring(data))
我得到的错误是:

IOError:无法找到此WMF文件的加载器

这些Word文档来自普通用户,他们可能只是从网络上剪切粘贴图像或从文件中插入图像。

在linux系统上有我的解决方案吗?

我试图将该文档上传到谷歌驱动器,图像也没有显示。也许没有简单的解决方案?

pip install Pillow
from PIL import Image
Image.open("xxx.wmf").save("xxx.png")

我发现使用Wand包进行这种转换更容易。我尝试了前面的建议,但没有成功。我是这样做的:(顺便说一句,我想转换所有'。Wmf ' files into pdf)

import os
from wand.image import Image as wima
folder='C:/Users/PythonLover/Pictures/pics'
for oldfilename in os.listdir(folder):
    if oldfilename.endswith(".wmf"):
        with wima(filename=folder+'/'+oldfilename) as img:
            newfilename = oldfilename.split('.')[0]+'.pdf'
            newfilename = folder+'/'+newfilename
            img.format = 'pdf'
            img.save(filename=newfilename)

您需要了解您正在处理的是什么,以便了解为什么您试图做的事情是有问题的。WMF文件(或最新的EMF和EMF+格式)需要Windows GDI来呈现它所描述的图像。因此,当您在Windows之外转换此格式时,没有简单的解决方案,因为您需要复制GDI API。

一个解决方案是使用unconv工具,它依赖于OpenOffice/LibreOffice的UNO绑定。第二种解决方案是使用pyemf模块解码输入,然后由第二个工具(由您完成)呈现它。

您可以使用libwmf将图像转换为SVG,然后使用pyrsvg转换为PNG(在另一个问题中描述)。

我没有找到libwmf项目网站,但是Debian(和Ubuntu)有包含wmf2svg实用程序的软件包libwmf-bin

WMF代表Windows Metafile;EMF代表增强型元文件。这些文件驱动Windows显示图像。在Microsoft Office应用程序中,它是矢量图像的标准格式。Metafile由Microsoft管理,不是开放格式。

由于libreoffice在Linux环境下是Microsoft Office的替代品,所以最好有一个小的服务,我们可以使用libreoffice和imagemagick(如果你不能安装它们)。

那么独立于语言的解决方案将是:

  1. 使用Dockerfile构建libreoffice容器(或者安装libreoffice)

    从linuxserver/libreoffice: 7.2.2

  2. 在容器中启动RESTful API(或RPC API),接收emf文件并返回png文件

  3. 在服务中我们实现了以下功能:
    a.将emf文件保存在一个路径中,例如/mnt/b。emf
    b.通过命令libreoffice --headless --convert-to png /mnt/b.emf将文件转换为任何语言;例如,在Python中,我们可以使用这个答案末尾的代码片段。
    c.读取png文件/mnt/b.png并通过API

    发送回来
  4. 使用imagemagick来修剪生成图像的空白

下面是Python的实现:

from os 
from flask import Flask, jsonify, request
def emf_to_png(im):
    temp_emf_path = '/tmp/temp.emf'
    temp_png_path = '/tmp/temp.png'
    with open(temp_emf_path, 'wb') as f: 
        f.write(im)
    command = f"libreoffice --headless --convert-to png {temp_emf_path} --outdir  /tmp"
    os.system(command)
    command = f'convert {temp_png_path} -fuzz 1% -trim +repage {temp_png_path}'
    os.system(command)
    f = open(temp_png_path, 'rb')
    png_b = f.read()
    f.close()
    os.remove(temp_emf_path)
    os.remove(temp_png_path)
    return png_b
app = Flask(__name__)
@app.route("/convert/emf2png", methods=["POST"])
def start_training():
    try:
        emf = request.data
        png_b = emf_to_png(emf)
        return jsonify(code=200, message="succeed", data=png_b)
    except Exception as e:
        return jsonify(code=100, message=f"error {e}")
if __name__ == '__main__':
    app.run("0.0.0.0", port=1111)

引用:

  1. https://stackoverflow.com/a/28749719/3552975
  2. https://ask.libreoffice.org/t/convert-to-jpg-wmf-on-linux-resolution-issue/44578

我有一个类似的问题,但我使用bash和inkscape将图像转换为png格式,我附加了执行此任务的小脚本:

#!/usr/bin/bash
for file in *.emf; do
  export_name=$(echo $file | sed 's/.emf$/.png/');
  echo inkscape $file -e $export_name
  inkscape $file -e $export_name
done

有关更多信息,请检查inkscape选项:

 inkscape --help
# -e, --export-png=FILE NAME

在linux上,您可以使用inkscapecommand (pip install Command)的帮助下完成从.emf.png的转换
我以前也试过pillowwand,它们都只在windows上工作。

import command
path_emf = 'path_to_your_emf_file'
path_png = 'path_to_save_png_file'
command.run(['inkscape', '-e', path_png, path_emf])

最新更新