diff --git a/src/sage/doctest/external.py b/src/sage/doctest/external.py index e1f00d0e740..480918b38fe 100644 --- a/src/sage/doctest/external.py +++ b/src/sage/doctest/external.py @@ -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:: diff --git a/src/sage/features/imagemagick.py b/src/sage/features/imagemagick.py index 526ac278877..fb273371326 100644 --- a/src/sage/features/imagemagick.py +++ b/src/sage/features/imagemagick.py @@ -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. """ @@ -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 @@ -78,9 +82,9 @@ def is_functional(self): 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', '-loop', '0', filename_png, filename_gif] try: @@ -110,7 +114,7 @@ class ImageMagick(JoinFeature): A :class:`~sage.features.Feature` describing the presence of :ref:`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:: @@ -127,7 +131,7 @@ def __init__(self): True """ JoinFeature.__init__(self, "imagemagick", - [Convert()], + [Magick()], spkg="imagemagick", url="https://www.imagemagick.org/") diff --git a/src/sage/graphs/graph_latex.py b/src/sage/graphs/graph_latex.py index 42cc1b369ab..b88dc892659 100644 --- a/src/sage/graphs/graph_latex.py +++ b/src/sage/graphs/graph_latex.py @@ -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 @@ -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 diff --git a/src/sage/misc/latex.py b/src/sage/misc/latex.py index 422aa90b89b..32aa0c94c66 100644 --- a/src/sage/misc/latex.py +++ b/src/sage/misc/latex.py @@ -681,14 +681,14 @@ def _run_latex_(filename, debug=False, density=150, engine=None, png=False, do_i 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)") print("appear to be installed. Displaying LaTeX, PDFLaTeX output") print("requires at least one of these programs, so please install") print("and try again.") @@ -696,7 +696,7 @@ def _run_latex_(filename, debug=False, density=150, engine=None, png=False, do_i 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 @@ -705,7 +705,7 @@ def _run_latex_(filename, debug=False, density=150, engine=None, png=False, do_i # 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: @@ -733,10 +733,11 @@ def _run_latex_(filename, debug=False, density=150, engine=None, png=False, do_i 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', '{0}x{0}'.format(density), '-trim', filename + '.' + suffix, filename + '.png'] @@ -754,10 +755,10 @@ def subpcall(x): if debug: print(lt) if png: - print(convert) + print(magick) e = subpcall(lt) if png: - e = e and subpcall(convert) + e = e and subpcall(magick) else: # latex if (png or check_validity): if dvipng().is_present(): @@ -768,19 +769,19 @@ def subpcall(x): 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...") print(dvips) - print(convert) - e = subpcall(dvips) and subpcall(convert) + print(magick) + e = subpcall(dvips) and subpcall(magick) else: - print("Error: 'dvipng' failed and 'convert' is not installed.") + print("Error: 'dvipng' failed and 'magick/convert' is not installed.") return "Error: dvipng failed." else: # not png, i.e., check_validity return_suffix = "pdf" @@ -796,12 +797,12 @@ def subpcall(x): 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) if not e: print("An error occurred.") try: @@ -902,7 +903,7 @@ class Latex(LatexCall): .. 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:: @@ -1013,9 +1014,9 @@ def eval(self, x, globals, strip=False, filename=None, debug=None, .. 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: diff --git a/src/sage/plot/animate.py b/src/sage/plot/animate.py index 2dbc162d07c..b5aae572283 100644 --- a/src/sage/plot/animate.py +++ b/src/sage/plot/animate.py @@ -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 @@ -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 @@ -567,11 +567,11 @@ def gif(self, delay=20, savefile=None, iterations=0, show_path=False, 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: @@ -589,7 +589,7 @@ def gif(self, delay=20, savefile=None, iterations=0, show_path=False, 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. @@ -651,7 +651,7 @@ def _gif_from_imagemagick(self, savefile=None, show_path=False, 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: @@ -690,12 +690,12 @@ def _gif_from_imagemagick(self, savefile=None, show_path=False, 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 ImageMagick().require() if not savefile: @@ -706,7 +706,7 @@ def _gif_from_imagemagick(self, savefile=None, show_path=False, # running the command directory = self.png() - cmd = ['convert', '-dispose', 'Background', + cmd = [Magick().executable, '-dispose', 'Background', '-delay', '%s' % int(delay), '-loop', '%s' % int(iterations), '*.png', savefile] from subprocess import run @@ -721,7 +721,7 @@ def _gif_from_imagemagick(self, savefile=None, show_path=False, 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. " @@ -825,7 +825,7 @@ def show(self, delay=None, iterations=None, **kwds): 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. @@ -1121,7 +1121,7 @@ def save(self, filename=None, show_path=False, use_ffmpeg=False, **kwds): 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 diff --git a/src/sage/plot/plot3d/tachyon.py b/src/sage/plot/plot3d/tachyon.py index 4dc3a9ce34a..c4f136ec157 100644 --- a/src/sage/plot/plot3d/tachyon.py +++ b/src/sage/plot/plot3d/tachyon.py @@ -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),