summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2017-04-22 22:10:21 +0100
committerMichael Williamson <mike@zwobble.org>2017-04-22 22:10:21 +0100
commitd03970a839cab967a8013ee5d18c74454d3174c1 (patch)
treebd84e3183e92658bc4636ff033aadfc7d363c456
parentc1eeb07720c452209d8c35b38aec9ae2bd76ca82 (diff)
Add image converters for WMF using LibreOffice and ImageMagick
-rw-r--r--mammoth/documents.py9
-rw-r--r--mammoth/images.py76
2 files changed, 80 insertions, 5 deletions
diff --git a/mammoth/documents.py b/mammoth/documents.py
index b1e2c1e..a6e125c 100644
--- a/mammoth/documents.py
+++ b/mammoth/documents.py
@@ -69,12 +69,11 @@ class Tab(Element):
pass
-@cobble.visitable
+@cobble.data
class Image(Element):
- def __init__(self, alt_text, content_type, open):
- self.alt_text = alt_text
- self.content_type = content_type
- self.open = open
+ alt_text = cobble.field()
+ content_type = cobble.field()
+ open = cobble.field()
def document(children, notes=None, comments=None):
diff --git a/mammoth/images.py b/mammoth/images.py
index 9dba353..9cc358c 100644
--- a/mammoth/images.py
+++ b/mammoth/images.py
@@ -1,4 +1,9 @@
import base64
+import io
+import os
+import shutil
+import subprocess
+import tempfile
from . import html
@@ -25,3 +30,74 @@ def data_uri(image):
return {
"src": "data:{0};base64,{1}".format(image.content_type, encoded_src)
}
+
+
+_wmf_extensions = {
+ "image/x-wmf": ".wmf",
+ "image/x-emf": ".emf",
+}
+
+
+def libreoffice_wmf_conversion(post_process=None):
+ if post_process is None:
+ post_process = lambda x: x
+
+ def convert_image(image):
+ 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)
+
+ return convert_image
+
+
+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)