Default quality to 0 which means don't specify

From the ImageMagick docs: "The default is to use the estimated quality
of your input image if it can be determined, otherwise 92."

In order to get the original behaviour we need to conditional add the
quality parameter to the `magick` call. The quality range can be
anything from 1 to 100, which gives us the convenience of using 0 to
specify no specific quality level.
This commit is contained in:
Daniel Barber 2020-02-18 14:50:57 -05:00
parent a30c90e615
commit 036202e1c5
5 changed files with 30 additions and 23 deletions

View file

@ -50,9 +50,9 @@ def get_art(log, item):
return mf.art return mf.art
def embed_item(log, item, imagepath, maxwidth=None, quality=75, itempath=None, def embed_item(log, item, imagepath, maxwidth=None, itempath=None,
compare_threshold=0, ifempty=False, as_album=False, compare_threshold=0, ifempty=False, as_album=False, id3v23=None,
id3v23=None): quality=0):
"""Embed an image into the item's media file. """Embed an image into the item's media file.
""" """
# Conditions and filters. # Conditions and filters.
@ -84,8 +84,8 @@ def embed_item(log, item, imagepath, maxwidth=None, quality=75, itempath=None,
item.try_write(path=itempath, tags={'images': [image]}, id3v23=id3v23) item.try_write(path=itempath, tags={'images': [image]}, id3v23=id3v23)
def embed_album(log, album, maxwidth=None, quality=75, quiet=False, def embed_album(log, album, maxwidth=None, quiet=False, compare_threshold=0,
compare_threshold=0, ifempty=False): ifempty=False, quality=0):
"""Embed album art into all of the album's items. """Embed album art into all of the album's items.
""" """
imagepath = album.artpath imagepath = album.artpath
@ -102,15 +102,16 @@ def embed_album(log, album, maxwidth=None, quality=75, quiet=False,
log.info(u'Embedding album art into {0}', album) log.info(u'Embedding album art into {0}', album)
for item in album.items(): for item in album.items():
embed_item(log, item, imagepath, maxwidth, quality, None, embed_item(log, item, imagepath, maxwidth, None, compare_threshold,
compare_threshold, ifempty, as_album=True) ifempty, as_album=True, quality=quality)
def resize_image(log, imagepath, maxwidth, quality): def resize_image(log, imagepath, maxwidth, quality):
"""Returns path to an image resized to maxwidth. """Returns path to an image resized to maxwidth.
""" """
log.debug(u'Resizing album art to {0} pixels wide', maxwidth) log.debug(u'Resizing album art to {0} pixels wide', maxwidth)
imagepath = ArtResizer.shared.resize(maxwidth, quality, syspath(imagepath)) imagepath = ArtResizer.shared.resize(maxwidth, syspath(imagepath),
quality=quality)
return imagepath return imagepath

View file

@ -59,7 +59,7 @@ def temp_file_for(path):
return util.bytestring_path(f.name) return util.bytestring_path(f.name)
def pil_resize(maxwidth, quality, path_in, path_out=None): def pil_resize(maxwidth, path_in, path_out=None, quality=0):
"""Resize using Python Imaging Library (PIL). Return the output path """Resize using Python Imaging Library (PIL). Return the output path
of resized image. of resized image.
""" """
@ -80,7 +80,7 @@ def pil_resize(maxwidth, quality, path_in, path_out=None):
return path_in return path_in
def im_resize(maxwidth, quality, path_in, path_out=None): def im_resize(maxwidth, path_in, path_out=None, quality=0):
"""Resize using ImageMagick. """Resize using ImageMagick.
Use the ``magick`` program or ``convert`` on older versions. Return Use the ``magick`` program or ``convert`` on older versions. Return
@ -93,11 +93,15 @@ def im_resize(maxwidth, quality, path_in, path_out=None):
# "-resize WIDTHx>" shrinks images with the width larger # "-resize WIDTHx>" shrinks images with the width larger
# than the given width while maintaining the aspect ratio # than the given width while maintaining the aspect ratio
# with regards to the height. # with regards to the height.
cmd = ArtResizer.shared.im_convert_cmd + \ cmd = ArtResizer.shared.im_convert_cmd + [
[util.syspath(path_in, prefix=False), util.syspath(path_in, prefix=False),
'-resize', '{0}x>'.format(maxwidth), '-resize', '{0}x>'.format(maxwidth),
'-quality', '{0}x'.format(quality), ]
util.syspath(path_out, prefix=False)]
if quality > 0:
cmd += ['-quality', '{0}'.format(quality)]
cmd.append(util.syspath(path_out, prefix=False))
try: try:
util.command_output(cmd) util.command_output(cmd)
@ -191,14 +195,14 @@ class ArtResizer(six.with_metaclass(Shareable, object)):
self.im_convert_cmd = ['magick'] self.im_convert_cmd = ['magick']
self.im_identify_cmd = ['magick', 'identify'] self.im_identify_cmd = ['magick', 'identify']
def resize(self, maxwidth, quality, path_in, path_out=None): def resize(self, maxwidth, path_in, path_out=None, quality=0):
"""Manipulate an image file according to the method, returning a """Manipulate an image file according to the method, returning a
new path. For PIL or IMAGEMAGIC methods, resizes the image to a new path. For PIL or IMAGEMAGIC methods, resizes the image to a
temporary file. For WEBPROXY, returns `path_in` unmodified. temporary file. For WEBPROXY, returns `path_in` unmodified.
""" """
if self.local: if self.local:
func = BACKEND_FUNCS[self.method[0]] func = BACKEND_FUNCS[self.method[0]]
return func(maxwidth, quality, path_in, path_out) return func(maxwidth, path_in, path_out, quality=quality)
else: else:
return path_in return path_in

View file

@ -422,7 +422,7 @@ class ConvertPlugin(BeetsPlugin):
util.displayable_path(album.artpath), util.displayable_path(album.artpath),
util.displayable_path(dest)) util.displayable_path(dest))
if not pretend: if not pretend:
ArtResizer.shared.resize(maxwidth, 75, album.artpath, dest) ArtResizer.shared.resize(maxwidth, album.artpath, dest)
else: else:
if pretend: if pretend:
msg = 'ln' if hardlink else ('ln -s' if link else 'cp') msg = 'ln' if hardlink else ('ln -s' if link else 'cp')

View file

@ -60,7 +60,7 @@ class EmbedCoverArtPlugin(BeetsPlugin):
'compare_threshold': 0, 'compare_threshold': 0,
'ifempty': False, 'ifempty': False,
'remove_art_file': False, 'remove_art_file': False,
'quality': 95, 'quality': 0,
}) })
if self.config['maxwidth'].get(int) and not ArtResizer.shared.local: if self.config['maxwidth'].get(int) and not ArtResizer.shared.local:
@ -107,7 +107,8 @@ class EmbedCoverArtPlugin(BeetsPlugin):
for item in items: for item in items:
art.embed_item(self._log, item, imagepath, maxwidth, art.embed_item(self._log, item, imagepath, maxwidth,
quality, None, compare_threshold, ifempty) None, compare_threshold, ifempty,
quality=quality)
else: else:
albums = lib.albums(decargs(args)) albums = lib.albums(decargs(args))
@ -116,8 +117,9 @@ class EmbedCoverArtPlugin(BeetsPlugin):
return return
for album in albums: for album in albums:
art.embed_album(self._log, album, maxwidth, quality, art.embed_album(self._log, album, maxwidth,
False, compare_threshold, ifempty) False, compare_threshold, ifempty,
quality=quality)
self.remove_artfile(album) self.remove_artfile(album)
embed_cmd.func = embed_func embed_cmd.func = embed_func

View file

@ -154,7 +154,7 @@ class ThumbnailsTest(unittest.TestCase, TestHelper):
any_order=True) any_order=True)
resize = mock_artresizer.shared.resize resize = mock_artresizer.shared.resize
resize.assert_called_once_with(12345, 75, path_to_art, md5_file) resize.assert_called_once_with(12345, path_to_art, md5_file)
plugin.add_tags.assert_called_once_with(album, resize.return_value) plugin.add_tags.assert_called_once_with(album, resize.return_value)
mock_shutils.move.assert_called_once_with(resize.return_value, mock_shutils.move.assert_called_once_with(resize.return_value,
md5_file) md5_file)