-
-
Notifications
You must be signed in to change notification settings - Fork 404
/
imagemagick.py
134 lines (108 loc) · 4.87 KB
/
imagemagick.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
r"""
Feature for testing the presence of ``imagemagick``
Currently we only check for the presence of ``convert``. When needed, other
commands like ``magick``, ``magick-script``, ``convert``, ``mogrify``,
``identify``, ``composite``, ``montage``, ``compare``, etc. could be also
checked in this module.
"""
# ****************************************************************************
# Copyright (C) 2018-2022 Sebastien Labbe <slabqc@gmail.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 of the License, or
# (at your option) any later version.
# https://www.gnu.org/licenses/
# ****************************************************************************
from . import Executable, FeatureTestResult
from .join_feature import JoinFeature
class Convert(Executable):
r"""
A :class:`~sage.features.Feature` describing the presence of ``convert``.
EXAMPLES::
sage: from sage.features.imagemagick import Convert
sage: Convert().is_present() # optional - imagemagick
FeatureTestResult('convert', True)
"""
def __init__(self):
r"""
TESTS::
sage: from sage.features.imagemagick import Convert
sage: isinstance(Convert(), Convert)
True
"""
Executable.__init__(self, "convert", executable="convert")
def is_functional(self):
r"""
Return whether command ``convert`` in the path is functional.
EXAMPLES::
sage: from sage.features.imagemagick import Convert
sage: Convert().is_functional() # optional - imagemagick
FeatureTestResult('convert', True)
"""
# Create the content of 1-pixel png file
content = b'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x01\x00\x00\x00\x01\x08\x00\x00\x00\x00:~\x9bU\x00\x00\x00\nIDATx\x9cc`\x00\x00\x00\x02\x00\x01H\xaf\xa4q\x00\x00\x00\x00IEND\xaeB`\x82'
# NOTE:
#
# This is how the above content of a 1 pixel PNG was created::
#
# sage: import numpy as np
# sage: from PIL import Image
# sage: image = Image.fromarray(np.array([[100]], dtype=np.uint8))
# sage: image.save('file.png')
# sage: with open('file.png', 'rb') as f:
# ....: content = f.read()
# create a png file with the content
from sage.misc.temporary_file import tmp_filename
base_filename_png = tmp_filename(ext='.png')
with open(base_filename_png, 'wb') as f:
f.write(content)
# Set up filenames
import os
base, filename_png = os.path.split(base_filename_png)
filename, _png = os.path.splitext(filename_png)
filename_gif = filename + '.gif'
# running command convert (taken from sage/plot/animate.py)
from subprocess import run
cmd = ['convert', '-dispose', 'Background', '-delay', '20',
'-loop', '0', filename_png, filename_gif]
try:
result = run(cmd, cwd=base, capture_output=True, text=True)
except OSError as e:
return FeatureTestResult(self, False, reason='Running command "{}" '
'raised an OSError "{}" '.format(' '.join(cmd), e))
# If an error occurred, return False
if result.returncode:
return FeatureTestResult(self, False, reason='Running command "{}" '
'returned non-zero exit status "{}" with stderr '
'"{}" and stdout "{}".'.format(result.args,
result.returncode,
result.stderr.strip(),
result.stdout.strip()))
# If necessary, run more tests here
# ...
# The command seems functional
return FeatureTestResult(self, True)
class ImageMagick(JoinFeature):
r"""
A :class:`~sage.features.Feature` describing the presence of
:ref:`ImageMagick <spkg_imagemagick>`
Currently, only the availability of the :class:`convert` program is checked.
EXAMPLES::
sage: from sage.features.imagemagick import ImageMagick
sage: ImageMagick().is_present() # optional - imagemagick
FeatureTestResult('imagemagick', True)
"""
def __init__(self):
r"""
TESTS::
sage: from sage.features.imagemagick import ImageMagick
sage: isinstance(ImageMagick(), ImageMagick)
True
"""
JoinFeature.__init__(self, "imagemagick",
[Convert()],
spkg="imagemagick",
url="https://www.imagemagick.org/")
def all_features():
return [ImageMagick()]