From 59b546f7483c3076291fa599a1d9d5b93be9d1c8 Mon Sep 17 00:00:00 2001 From: Antony Lee Date: Tue, 2 Oct 2018 17:38:46 +0200 Subject: [PATCH] Move check for ImageMagick Windows path to bin_path(). That's a perfectly reasonable place to put the registry check and avoids introducing an additional private helper method. --- lib/matplotlib/animation.py | 76 ++++++++++++++----------------------- 1 file changed, 29 insertions(+), 47 deletions(-) diff --git a/lib/matplotlib/animation.py b/lib/matplotlib/animation.py index b3ed6da0e6a6..1f50f9c7ac11 100644 --- a/lib/matplotlib/animation.py +++ b/lib/matplotlib/animation.py @@ -700,7 +700,7 @@ class AVConvFileWriter(AVConvBase, FFMpegFileWriter): ''' -# Base class for animated GIFs with convert utility +# Base class for animated GIFs with ImageMagick class ImageMagickBase(object): '''Mixin class for ImageMagick output. @@ -720,48 +720,33 @@ def output_args(self): return [self.outfile] @classmethod - def _init_from_registry(cls): - if sys.platform != 'win32' or rcParams[cls.exec_key] != 'convert': - return - import winreg - for flag in (0, winreg.KEY_WOW64_32KEY, winreg.KEY_WOW64_64KEY): - try: - hkey = winreg.OpenKeyEx(winreg.HKEY_LOCAL_MACHINE, - r'Software\Imagemagick\Current', - 0, winreg.KEY_QUERY_VALUE | flag) - binpath = winreg.QueryValueEx(hkey, 'BinPath')[0] - winreg.CloseKey(hkey) - break - except Exception: - binpath = '' - if binpath: - for exe in ('convert.exe', 'magick.exe'): - path = os.path.join(binpath, exe) - if os.path.exists(path): - binpath = path - break - else: - binpath = '' - rcParams[cls.exec_key] = rcParamsDefault[cls.exec_key] = binpath - - @classmethod - def isAvailable(cls): - ''' - Check to see if a ImageMagickWriter is actually available. - - Done by first checking the windows registry (if applicable) and then - running the commandline tool. - ''' - bin_path = cls.bin_path() - if bin_path == "convert": - cls._init_from_registry() - return super().isAvailable() - - -# Note: the base classes need to be in that order to get -# isAvailable() from ImageMagickBase called and not the -# one from MovieWriter. The latter is then called by the -# former. + def bin_path(cls): + binpath = super().bin_path() + if sys.platform == 'win32' and binpath == 'convert': + # Check the registry to avoid confusing ImageMagick's convert with + # Windows's builtin convert.exe. + import winreg + binpath = '' + for flag in (0, winreg.KEY_WOW64_32KEY, winreg.KEY_WOW64_64KEY): + try: + with winreg.OpenKeyEx( + winreg.HKEY_LOCAL_MACHINE, + r'Software\Imagemagick\Current', + 0, winreg.KEY_QUERY_VALUE | flag) as hkey: + parent = winreg.QueryValueEx(hkey, 'BinPath')[0] + except OSError: + pass + if binpath: + for exe in ('convert.exe', 'magick.exe'): + candidate = os.path.join(parent, exe) + if os.path.exists(candidate): + binpath = candidate + break + rcParams[cls.exec_key] = rcParamsDefault[cls.exec_key] = binpath + return binpath + + +# Combine ImageMagick options with pipe-based writing @writers.register('imagemagick') class ImageMagickWriter(ImageMagickBase, MovieWriter): '''Pipe-based animated gif. @@ -778,10 +763,7 @@ def _args(self): + self.output_args) -# Note: the base classes need to be in that order to get -# isAvailable() from ImageMagickBase called and not the -# one from MovieWriter. The latter is then called by the -# former. +# Combine ImageMagick options with temp file-based writing @writers.register('imagemagick_file') class ImageMagickFileWriter(ImageMagickBase, FileMovieWriter): '''File-based animated gif writer.