From 2da325b72414ef43b3db9713b1c46d97685171bb Mon Sep 17 00:00:00 2001 From: Michael Williamson Date: Wed, 6 Sep 2017 20:10:18 +0100 Subject: Move WMF image handler to recipes directory --- recipes/wmf_images.py | 103 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 103 insertions(+) create mode 100644 recipes/wmf_images.py (limited to 'recipes') diff --git a/recipes/wmf_images.py b/recipes/wmf_images.py new file mode 100644 index 0000000..afea437 --- /dev/null +++ b/recipes/wmf_images.py @@ -0,0 +1,103 @@ +import io +import os +import shutil +import subprocess +import tempfile + + +# An example of how to use LibreOffice and ImageMagick to convert WMF images to +# PNGs. +# +# libreoffice_wmf_conversion uses LibreOffice to convert the image to a PNG. +# This normally creates an image with a large amount of padding, so +# imagemagick_trim can be used to trim the image. +# +# The image can be then be converted using a normal image handler, such as +# mammoth.images.data_uri. +# +# Example usage: +# +# def convert_image(image): +# image = libreoffice_wmf_conversion(image, post_process=imagemagick_trim) +# return mammoth.images.data_uri(image) +# +# +# fileobj = open("document.docx", "rb") +# result = mammoth.convert_to_html( +# fileobj, +# convert_image=compose( +# mammoth.images.data_uri, +# libreoffice_wmf_conversion(post_process=imagemagick_trim), +# ), +# ) +# +# libreoffice_wmf_conversion uses LibreOffice to convert the image + + +_wmf_extensions = { + "image/x-wmf": ".wmf", + "image/x-emf": ".emf", +} + + +def libreoffice_wmf_conversion(image, post_process=None): + if post_process is None: + post_process = lambda x: x + + wmf_extension = _wmf_extensions.get(image.content_type) + if wmf_extension is None: + return image + else: + temporary_directory = tempfile.mkdtemp() + try: + input_path = os.path.join(temporary_directory, "image" + wmf_extension) + with io.open(input_path, "wb") as input_fileobj: + with image.open() as image_fileobj: + shutil.copyfileobj(image_fileobj, input_fileobj) + + output_path = os.path.join(temporary_directory, "image.png") + subprocess.check_call([ + "libreoffice", + "--headless", + "--convert-to", + "png", + input_path, + "--outdir", + temporary_directory, + ]) + + with io.open(output_path, "rb") as output_fileobj: + output = output_fileobj.read() + + def open_image(): + return io.BytesIO(output) + + return post_process(image.copy( + content_type="image/png", + open=open_image, + )) + finally: + shutil.rmtree(temporary_directory) + + +def imagemagick_trim(image): + command = ["convert", "-", "-trim", "-"] + process = subprocess.Popen(command, stdin=subprocess.PIPE, stdout=subprocess.PIPE) + try: + with image.open() as image_fileobj: + shutil.copyfileobj(image_fileobj, process.stdin) + output, err_output = process.communicate() + except: + process.kill() + process.wait() + raise + + return_code = process.poll() + if return_code: + raise subprocess.CalledProcessError(return_code, command) + else: + def open_image(): + return io.BytesIO(output) + + return image.copy(open=open_image) + -- cgit v1.2.3