Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use magick command instead of the deprecated convert if available #38135

Merged
merged 5 commits into from
Jul 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/sage/doctest/external.py
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,7 @@ def has_ffmpeg():

def has_imagemagick():
"""
Test if ImageMagick (command convert) is available.
Test if ImageMagick (command magick or convert) is available.

EXAMPLES::

Expand Down
40 changes: 22 additions & 18 deletions src/sage/features/imagemagick.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
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``,
Currently we only check for the presence of ``convert`` or ``magick``. When needed, other
commands like ``magick-script``, ``mogrify``,
``identify``, ``composite``, ``montage``, ``compare``, etc. could be also
checked in this module.
"""
Expand All @@ -21,35 +21,39 @@
from . import Executable, FeatureTestResult
from .join_feature import JoinFeature

class Convert(Executable):
class Magick(Executable):
r"""
A :class:`~sage.features.Feature` describing the presence of ``convert``.
A :class:`~sage.features.Feature` describing the presence of ``magick`` or the deprecated ``convert``.

EXAMPLES::

sage: from sage.features.imagemagick import Convert
sage: Convert().is_present() # optional - imagemagick
FeatureTestResult('convert', True)
sage: from sage.features.imagemagick import Magick
sage: Magick().is_present() # optional - imagemagick
FeatureTestResult('magick', True)
"""
def __init__(self):
r"""
TESTS::

sage: from sage.features.imagemagick import Convert
sage: isinstance(Convert(), Convert)
sage: from sage.features.imagemagick import Magick
sage: isinstance(Magick(), Magick)
True
"""
Executable.__init__(self, "convert", executable="convert")
Executable.__init__(self, "magick", executable="magick")
try:
_ = self.absolute_filename()
except RuntimeError:
Executable.__init__(self, "magick", executable="convert")

def is_functional(self):
r"""
Return whether command ``convert`` in the path is functional.
Return whether command ``magick`` or ``convert`` in the path is functional.

EXAMPLES::

sage: from sage.features.imagemagick import Convert
sage: Convert().is_functional() # optional - imagemagick
FeatureTestResult('convert', True)
sage: from sage.features.imagemagick import Magick
sage: Magick().is_functional() # optional - imagemagick
FeatureTestResult('magick', True)

"""
# Create the content of 1-pixel png file
Expand Down Expand Up @@ -78,9 +82,9 @@
filename, _png = os.path.splitext(filename_png)
filename_gif = filename + '.gif'

# running command convert (taken from sage/plot/animate.py)
# running command magick/convert (taken from sage/plot/animate.py)
from subprocess import run
cmd = ['convert', '-dispose', 'Background', '-delay', '20',
cmd = [self.executable, '-dispose', 'Background', '-delay', '20',

Check warning on line 87 in src/sage/features/imagemagick.py

View check run for this annotation

Codecov / codecov/patch

src/sage/features/imagemagick.py#L87

Added line #L87 was not covered by tests
'-loop', '0', filename_png, filename_gif]

try:
Expand Down Expand Up @@ -110,7 +114,7 @@
A :class:`~sage.features.Feature` describing the presence of
:ref:`ImageMagick <spkg_imagemagick>`

Currently, only the availability of the :class:`convert` program is checked.
Currently, only the availability of the :class:`magick` (or :class:`convert`) program is checked.

EXAMPLES::

Expand All @@ -127,7 +131,7 @@
True
"""
JoinFeature.__init__(self, "imagemagick",
[Convert()],
[Magick()],
spkg="imagemagick",
url="https://www.imagemagick.org/")

Expand Down
4 changes: 2 additions & 2 deletions src/sage/graphs/graph_latex.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@
the four compass points

To use LaTeX in Sage you of course need a working TeX installation and it will
work best if you have the ``dvipng`` and ``convert`` utilities. For graphs you
work best if you have the ``dvipng`` and ``magick`` utilities. For graphs you
need the ``tkz-graph.sty`` and ``tkz-berge.sty`` style files of the tkz-graph
package. TeX, dvipng, and convert should be widely available through package
managers or installers. You may need to install the tkz-graph style files in
Expand All @@ -69,7 +69,7 @@

- TeX: http://ctan.org/
- dvipng: http://sourceforge.net/projects/dvipng/
- convert: http://www.imagemagick.org (the ImageMagick suite)
- magick: http://www.imagemagick.org (the ImageMagick suite)
- tkz-graph: https://www.ctan.org/pkg/tkz-graph

Customizing the output is accomplished in several ways. Suppose ``g`` is a
Expand Down
41 changes: 21 additions & 20 deletions src/sage/misc/latex.py
Original file line number Diff line number Diff line change
Expand Up @@ -681,22 +681,22 @@
else:
raise ValueError("Unsupported LaTeX engine.")

# if png output + latex, check to see if dvipng or convert is installed.
# if png output + latex, check to see if dvipng or magick/convert is installed.
from sage.features.imagemagick import ImageMagick
from sage.features.dvipng import dvipng
if png:
if ((not engine or engine == "latex")
and not (dvipng().is_present() or ImageMagick().is_present())):
print()
print("Error: neither dvipng nor convert (from the ImageMagick suite)")
print("Error: neither dvipng nor magick/convert (from the ImageMagick suite)")

Check warning on line 691 in src/sage/misc/latex.py

View check run for this annotation

Codecov / codecov/patch

src/sage/misc/latex.py#L691

Added line #L691 was not covered by tests
print("appear to be installed. Displaying LaTeX, PDFLaTeX output")
print("requires at least one of these programs, so please install")
print("and try again.")
print()
print("Go to http://sourceforge.net/projects/dvipng/ and")
print("http://www.imagemagick.org to download these programs.")
return "Error"
# if png output + [pdf|xe|lua]latex, check to see if convert is installed.
# if png output + [pdf|xe|lua]latex, check to see if magick/convert is installed.
elif engine in ["pdflatex", "xelatex", "lualatex"]:
ImageMagick().require()
# check_validity: check to see if the dvi file is okay by trying
Expand All @@ -705,7 +705,7 @@
# function.
#
# thus if not png output, check validity of dvi output if dvipng
# or convert is installed.
# or magick/convert is installed.
else:
check_validity = dvipng().is_present()
# set up filenames, other strings:
Expand Down Expand Up @@ -733,10 +733,11 @@

ps2pdf = ['ps2pdf', filename + '.ps']

# We seem to need a larger size when using convert compared to
# We seem to need a larger size when using magick/convert compared to
# when using dvipng:
density = int(1.4 * density / 1.3)
convert = ['convert', '-density',
from sage.features.imagemagick import Magick
magick = [Magick().executable, '-density',

Check warning on line 740 in src/sage/misc/latex.py

View check run for this annotation

Codecov / codecov/patch

src/sage/misc/latex.py#L739-L740

Added lines #L739 - L740 were not covered by tests
'{0}x{0}'.format(density), '-trim', filename + '.' + suffix,
filename + '.png']

Expand All @@ -754,10 +755,10 @@
if debug:
print(lt)
if png:
print(convert)
print(magick)

Check warning on line 758 in src/sage/misc/latex.py

View check run for this annotation

Codecov / codecov/patch

src/sage/misc/latex.py#L758

Added line #L758 was not covered by tests
e = subpcall(lt)
if png:
e = e and subpcall(convert)
e = e and subpcall(magick)

Check warning on line 761 in src/sage/misc/latex.py

View check run for this annotation

Codecov / codecov/patch

src/sage/misc/latex.py#L761

Added line #L761 was not covered by tests
else: # latex
if (png or check_validity):
if dvipng().is_present():
Expand All @@ -768,19 +769,19 @@
dvipng_error = not os.path.exists(os.path.join(base, filename + '.png'))
# If there is no png file, then either the latex
# process failed or dvipng failed. Assume that dvipng
# failed, and try running dvips and convert. (If the
# latex process failed, then dvips and convert will
# failed, and try running dvips and magick/convert. (If the
# latex process failed, then dvips and magick/convert will
# fail also, so we'll still catch the error.)
if dvipng_error:
if png:
if ImageMagick().is_present():
if debug:
print("'dvipng' failed; trying 'convert' instead...")
print("'dvipng' failed; trying 'magick/convert' instead...")

Check warning on line 779 in src/sage/misc/latex.py

View check run for this annotation

Codecov / codecov/patch

src/sage/misc/latex.py#L779

Added line #L779 was not covered by tests
print(dvips)
print(convert)
e = subpcall(dvips) and subpcall(convert)
print(magick)
e = subpcall(dvips) and subpcall(magick)

Check warning on line 782 in src/sage/misc/latex.py

View check run for this annotation

Codecov / codecov/patch

src/sage/misc/latex.py#L781-L782

Added lines #L781 - L782 were not covered by tests
else:
print("Error: 'dvipng' failed and 'convert' is not installed.")
print("Error: 'dvipng' failed and 'magick/convert' is not installed.")

Check warning on line 784 in src/sage/misc/latex.py

View check run for this annotation

Codecov / codecov/patch

src/sage/misc/latex.py#L784

Added line #L784 was not covered by tests
return "Error: dvipng failed."
else: # not png, i.e., check_validity
return_suffix = "pdf"
Expand All @@ -796,12 +797,12 @@
print("error running dvips and ps2pdf; trying pdflatex instead...")
print(pdflt)
e = subpcall(pdflt)
else: # do not have dvipng, so must have convert. run latex, dvips, convert.
else: # do not have dvipng, so must have magick/convert. run latex, dvips, magick/convert.
if debug:
print(lt)
print(dvips)
print(convert)
e = subpcall(lt) and subpcall(dvips) and subpcall(convert)
print(magick)
e = subpcall(lt) and subpcall(dvips) and subpcall(magick)

Check warning on line 805 in src/sage/misc/latex.py

View check run for this annotation

Codecov / codecov/patch

src/sage/misc/latex.py#L804-L805

Added lines #L804 - L805 were not covered by tests
if not e:
print("An error occurred.")
try:
Expand Down Expand Up @@ -902,7 +903,7 @@

.. WARNING::

You must have dvipng (or dvips and convert) installed
You must have dvipng (or dvips and magick/convert) installed
on your operating system, or this command will not work.

EXAMPLES::
Expand Down Expand Up @@ -1013,9 +1014,9 @@
.. WARNING::

When using ``'latex'`` (the default), you must have ``dvipng`` (or
``dvips`` and ``convert``) installed on your operating system, or
``dvips`` and ``magick/convert``) installed on your operating system, or
this command will not work. When using ``'pdflatex'``, ``'xelatex'``
or ``'lualatex'``, you must have ``convert`` installed.
or ``'lualatex'``, you must have ``magick/convert`` installed.

OUTPUT:

Expand Down
26 changes: 13 additions & 13 deletions src/sage/plot/animate.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
object, creating a sequence of PNG files.
These are then assembled to various target formats using different
tools.
In particular, the ``convert`` program from ImageMagick_ can be used to
In particular, the ``magick/convert`` program from ImageMagick_ can be used to
generate an animated GIF file.
FFmpeg_ (with the command line program ``ffmpeg``) provides support for
various video formats, but also an alternative method of generating
Expand All @@ -20,7 +20,7 @@

Note that ``ImageMagick`` and ``FFmpeg`` are not included with Sage, and
must be installed by the user. On unix systems, type ``which
convert`` at a command prompt to see if ``convert`` (part of the
magick`` at a command prompt to see if ``magick`` (part of the
``ImageMagick`` suite) is installed. If it is, you will be given its
location. Similarly, you can check for ``ffmpeg`` with ``which
ffmpeg``. See the websites of ImageMagick_ or FFmpeg_ for
Expand Down Expand Up @@ -567,11 +567,11 @@
objects in self.

This method will only work if either (a) the ImageMagick
software suite is installed, i.e., you have the ``convert``
software suite is installed, i.e., you have the ``magick/convert``
command or (b) ``ffmpeg`` is installed. See the web sites of
ImageMagick_ and FFmpeg_ for more details. By default, this
produces the gif using ``convert`` if it is present. If this
can't find ``convert`` or if ``use_ffmpeg`` is True, then it
produces the gif using Imagemagick if it is present. If this
can't find ImageMagick or if ``use_ffmpeg`` is True, then it
uses ``ffmpeg`` instead.

INPUT:
Expand All @@ -589,7 +589,7 @@
print the path to the saved file

- ``use_ffmpeg`` -- boolean (default: ``False``); if True, use
'ffmpeg' by default instead of 'convert'.
'ffmpeg' by default instead of ImageMagick

If ``savefile`` is not specified: in notebook mode, display the
animation; otherwise, save it to a default file name.
Expand Down Expand Up @@ -651,7 +651,7 @@
the frames in ``self``.

This method will only work if ``imagemagick`` is installed (command
``convert``). See https://www.imagemagick.org for information
``magick`` or ``convert``). See https://www.imagemagick.org for information
about ``imagemagick``.

INPUT:
Expand Down Expand Up @@ -690,12 +690,12 @@
like this::

FeatureNotPresentError: imagemagick is not available.
Executable 'convert' not found on PATH.
Executable 'magick' not found on PATH.
Further installation instructions might be available at
https://www.imagemagick.org/.

"""
from sage.features.imagemagick import ImageMagick
from sage.features.imagemagick import ImageMagick, Magick

Check warning on line 698 in src/sage/plot/animate.py

View check run for this annotation

Codecov / codecov/patch

src/sage/plot/animate.py#L698

Added line #L698 was not covered by tests
ImageMagick().require()

if not savefile:
Expand All @@ -706,7 +706,7 @@

# running the command
directory = self.png()
cmd = ['convert', '-dispose', 'Background',
cmd = [Magick().executable, '-dispose', 'Background',

Check warning on line 709 in src/sage/plot/animate.py

View check run for this annotation

Codecov / codecov/patch

src/sage/plot/animate.py#L709

Added line #L709 was not covered by tests
'-delay', '%s' % int(delay), '-loop', '%s' % int(iterations),
'*.png', savefile]
from subprocess import run
Expand All @@ -721,7 +721,7 @@
result.stderr.strip(),
result.stdout.strip()))
raise OSError("Error: Cannot generate GIF animation. "
"The convert command (ImageMagick) is present but does "
"The magick/convert command (ImageMagick) is present but does "
"not seem to be functional. Verify that the objects "
"passed to the animate command can be saved in PNG "
"image format. "
Expand Down Expand Up @@ -825,7 +825,7 @@
Currently this is done using an animated gif, though this
could change in the future. This requires that either
ffmpeg or the ImageMagick suite (in particular, the
``convert`` command) is installed.
``magick/convert`` command) is installed.

See also the :meth:`ffmpeg` method.

Expand Down Expand Up @@ -1121,7 +1121,7 @@
print the path to the saved file

- ``use_ffmpeg`` -- boolean (default: ``False``); if True, use
'ffmpeg' by default instead of 'convert' when creating GIF
'ffmpeg' by default instead of ImageMagick when creating GIF
files.

If filename is None, then in notebook mode, display the
Expand Down
4 changes: 2 additions & 2 deletions src/sage/plot/plot3d/tachyon.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,8 +123,8 @@
sage: fname_png = tmp_filename(ext='.png')
sage: fname_ppm = tmp_filename(ext='.ppm')
sage: T.save(fname_png)
sage: r2 = os.system('convert '+fname_png+' '+fname_ppm) # optional -- ImageMagick

sage: from sage.features.imagemagick import Magick
sage: r2 = os.system(Magick().executable+' '+fname_png+' '+fname_ppm) # optional -- ImageMagick
sage: # optional - imagemagick
sage: T = Tachyon(xres=800, yres=600,
....: camera_position=(-2.0,-.1,.3),
Expand Down
Loading