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

Update artresizer's ImageMagick commands to use the magick binary #3236

Merged
merged 9 commits into from
Apr 30, 2019
77 changes: 49 additions & 28 deletions beets/util/artresizer.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,8 @@ def pil_resize(maxwidth, path_in, path_out=None):


def im_resize(maxwidth, path_in, path_out=None):
"""Resize using ImageMagick's ``convert`` tool.
"""Resize using ImageMagick's ``magick`` tool
(or fall back to ``convert`` for older versions.)
kassisaf marked this conversation as resolved.
Show resolved Hide resolved
Return the output path of resized image.
"""
path_out = path_out or temp_file_for(path_in)
Expand All @@ -92,11 +93,13 @@ def im_resize(maxwidth, path_in, path_out=None):
# than the given width while maintaining the aspect ratio
# with regards to the height.
try:
util.command_output([
'convert', util.syspath(path_in, prefix=False),
'-resize', '{0}x>'.format(maxwidth),
util.syspath(path_out, prefix=False),
])
cmds = (['magick'], ['convert'])
kassisaf marked this conversation as resolved.
Show resolved Hide resolved
cmd = cmds[0] if not ArtResizer.shared.im_legacy else cmds[1]
kassisaf marked this conversation as resolved.
Show resolved Hide resolved
args = [util.syspath(path_in, prefix=False),
'-resize', '{0}x>'.format(maxwidth),
util.syspath(path_out, prefix=False)]
kassisaf marked this conversation as resolved.
Show resolved Hide resolved

util.command_output(cmd + args)
except subprocess.CalledProcessError:
log.warning(u'artresizer: IM convert failed for {0}',
util.displayable_path(path_in))
Expand All @@ -121,10 +124,12 @@ def pil_getsize(path_in):


def im_getsize(path_in):
cmd = ['identify', '-format', '%w %h',
util.syspath(path_in, prefix=False)]
cmds = (['magick', 'identify'], ['identify'])
cmd = cmds[0] if not ArtResizer.shared.im_legacy else cmds[1]
args = ['-format', '%w %h', util.syspath(path_in, prefix=False)]
kassisaf marked this conversation as resolved.
Show resolved Hide resolved

try:
out = util.command_output(cmd)
out = util.command_output(cmd + args)
except subprocess.CalledProcessError as exc:
log.warning(u'ImageMagick size query failed')
log.debug(
Expand Down Expand Up @@ -173,6 +178,9 @@ def __init__(self):
log.debug(u"artresizer: method is {0}", self.method)
self.can_compare = self._can_compare()

if self.method[0] == IMAGEMAGICK:
kassisaf marked this conversation as resolved.
Show resolved Hide resolved
self.im_legacy = self.method[2]

def resize(self, maxwidth, path_in, path_out=None):
"""Manipulate an image file according to the method, returning a
new path. For PIL or IMAGEMAGIC methods, resizes the image to a
Expand Down Expand Up @@ -219,9 +227,12 @@ def _can_compare(self):
@staticmethod
def _check_method():
"""Return a tuple indicating an available method and its version."""
kassisaf marked this conversation as resolved.
Show resolved Hide resolved
version = get_im_version()
if version:
return IMAGEMAGICK, version
try:
version, im_legacy = get_im_version()
if version:
return IMAGEMAGICK, version, im_legacy
kassisaf marked this conversation as resolved.
Show resolved Hide resolved
except TypeError:
pass

version = get_pil_version()
if version:
Expand All @@ -232,23 +243,33 @@ def _check_method():

def get_im_version():
"""Return Image Magick version or None if it is unavailable
Try invoking ImageMagick's "convert".
Try invoking ImageMagick's "magick". If "magick" is unavailable,
as with older versions, fall back to "convert"

Our iterator `im_legacy` will be non-zero when the first command
fails, and will be returned in a tuple along with the version
"""
try:
out = util.command_output(['convert', '--version'])

if b'imagemagick' in out.lower():
pattern = br".+ (\d+)\.(\d+)\.(\d+).*"
match = re.search(pattern, out)
if match:
return (int(match.group(1)),
int(match.group(2)),
int(match.group(3)))
return (0,)

except (subprocess.CalledProcessError, OSError) as exc:
log.debug(u'ImageMagick check `convert --version` failed: {}', exc)
return None
cmds = ('magick', 'convert')
for im_legacy, cmd in enumerate(cmds):

try:
out = util.command_output([cmd, '--version'])

if b'imagemagick' in out.lower():
pattern = br".+ (\d+)\.(\d+)\.(\d+).*"
match = re.search(pattern, out)
if match:
return ((int(match.group(1)),
int(match.group(2)),
int(match.group(3))),
bool(im_legacy)
)
kassisaf marked this conversation as resolved.
Show resolved Hide resolved

except (subprocess.CalledProcessError, OSError) as exc:
log.debug(u'ImageMagick version check failed: {}', exc)
return None

return (0,)
kassisaf marked this conversation as resolved.
Show resolved Hide resolved


def get_pil_version():
Expand Down