Allow the quality to be set for embedded/fetched cover art

This commit is contained in:
Daniel Barber 2019-12-15 16:37:21 -05:00
parent de6173a6f4
commit 86946ad4b7
6 changed files with 23 additions and 20 deletions

View file

@ -50,7 +50,7 @@ def get_art(log, item):
return mf.art
def embed_item(log, item, imagepath, maxwidth=None, itempath=None,
def embed_item(log, item, imagepath, maxwidth=None, quality=75, itempath=None,
compare_threshold=0, ifempty=False, as_album=False,
id3v23=None):
"""Embed an image into the item's media file.
@ -64,7 +64,7 @@ def embed_item(log, item, imagepath, maxwidth=None, itempath=None,
log.info(u'media file already contained art')
return
if maxwidth and not as_album:
imagepath = resize_image(log, imagepath, maxwidth)
imagepath = resize_image(log, imagepath, maxwidth, quality)
# Get the `Image` object from the file.
try:
@ -84,7 +84,7 @@ def embed_item(log, item, imagepath, maxwidth=None, itempath=None,
item.try_write(path=itempath, tags={'images': [image]}, id3v23=id3v23)
def embed_album(log, album, maxwidth=None, quiet=False,
def embed_album(log, album, maxwidth=None, quality=75, quiet=False,
compare_threshold=0, ifempty=False):
"""Embed album art into all of the album's items.
"""
@ -97,20 +97,20 @@ def embed_album(log, album, maxwidth=None, quiet=False,
displayable_path(imagepath), album)
return
if maxwidth:
imagepath = resize_image(log, imagepath, maxwidth)
imagepath = resize_image(log, imagepath, maxwidth, quality)
log.info(u'Embedding album art into {0}', album)
for item in album.items():
embed_item(log, item, imagepath, maxwidth, None,
embed_item(log, item, imagepath, maxwidth, quality, None,
compare_threshold, ifempty, as_album=True)
def resize_image(log, imagepath, maxwidth):
def resize_image(log, imagepath, maxwidth, quality):
"""Returns path to an image resized to maxwidth.
"""
log.debug(u'Resizing album art to {0} pixels wide', maxwidth)
imagepath = ArtResizer.shared.resize(maxwidth, syspath(imagepath))
imagepath = ArtResizer.shared.resize(maxwidth, quality, syspath(imagepath))
return imagepath

View file

@ -59,7 +59,7 @@ def temp_file_for(path):
return util.bytestring_path(f.name)
def pil_resize(maxwidth, path_in, path_out=None):
def pil_resize(maxwidth, quality, path_in, path_out=None):
"""Resize using Python Imaging Library (PIL). Return the output path
of resized image.
"""
@ -72,7 +72,7 @@ def pil_resize(maxwidth, path_in, path_out=None):
im = Image.open(util.syspath(path_in))
size = maxwidth, maxwidth
im.thumbnail(size, Image.ANTIALIAS)
im.save(util.py3_path(path_out))
im.save(util.py3_path(path_out), quality=quality)
return path_out
except IOError:
log.error(u"PIL cannot create thumbnail for '{0}'",
@ -80,7 +80,7 @@ def pil_resize(maxwidth, path_in, path_out=None):
return path_in
def im_resize(maxwidth, path_in, path_out=None):
def im_resize(maxwidth, quality, path_in, path_out=None):
"""Resize using ImageMagick.
Use the ``magick`` program or ``convert`` on older versions. Return
@ -96,6 +96,7 @@ def im_resize(maxwidth, path_in, path_out=None):
cmd = ArtResizer.shared.im_convert_cmd + \
[util.syspath(path_in, prefix=False),
'-resize', '{0}x>'.format(maxwidth),
'-quality', '{0}x'.format(quality),
util.syspath(path_out, prefix=False)]
try:
@ -190,14 +191,14 @@ class ArtResizer(six.with_metaclass(Shareable, object)):
self.im_convert_cmd = ['magick']
self.im_identify_cmd = ['magick', 'identify']
def resize(self, maxwidth, path_in, path_out=None):
def resize(self, maxwidth, quality, 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
temporary file. For WEBPROXY, returns `path_in` unmodified.
"""
if self.local:
func = BACKEND_FUNCS[self.method[0]]
return func(maxwidth, path_in, path_out)
return func(maxwidth, quality, path_in, path_out)
else:
return path_in

View file

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

View file

@ -59,7 +59,8 @@ class EmbedCoverArtPlugin(BeetsPlugin):
'auto': True,
'compare_threshold': 0,
'ifempty': False,
'remove_art_file': False
'remove_art_file': False,
'quality': 95,
})
if self.config['maxwidth'].get(int) and not ArtResizer.shared.local:
@ -86,6 +87,7 @@ class EmbedCoverArtPlugin(BeetsPlugin):
u"-y", u"--yes", action="store_true", help=u"skip confirmation"
)
maxwidth = self.config['maxwidth'].get(int)
quality = self.config['quality'].get(int)
compare_threshold = self.config['compare_threshold'].get(int)
ifempty = self.config['ifempty'].get(bool)
@ -104,8 +106,8 @@ class EmbedCoverArtPlugin(BeetsPlugin):
return
for item in items:
art.embed_item(self._log, item, imagepath, maxwidth, None,
compare_threshold, ifempty)
art.embed_item(self._log, item, imagepath, maxwidth,
quality, None, compare_threshold, ifempty)
else:
albums = lib.albums(decargs(args))
@ -114,8 +116,8 @@ class EmbedCoverArtPlugin(BeetsPlugin):
return
for album in albums:
art.embed_album(self._log, album, maxwidth, False,
compare_threshold, ifempty)
art.embed_album(self._log, album, maxwidth, quality,
False, compare_threshold, ifempty)
self.remove_artfile(album)
embed_cmd.func = embed_func

View file

@ -135,7 +135,7 @@ class Candidate(object):
def resize(self, plugin):
if plugin.maxwidth and self.check == self.CANDIDATE_DOWNSCALE:
self.path = ArtResizer.shared.resize(plugin.maxwidth, self.path)
self.path = ArtResizer.shared.resize(plugin.maxwidth, 75, self.path)
def _logged_get(log, *args, **kwargs):

View file

@ -152,7 +152,7 @@ class ThumbnailsPlugin(BeetsPlugin):
self._log.debug(u"{1}x{1} thumbnail for {0} exists and is "
u"recent enough", album, size)
return False
resized = ArtResizer.shared.resize(size, album.artpath,
resized = ArtResizer.shared.resize(size, 75, album.artpath,
util.syspath(target))
self.add_tags(album, util.syspath(resized))
shutil.move(resized, target)