From dd25e1a82564f7375dabff2f9d9a5bef1f986d0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotrek=20Kocha=C5=84ski?= Date: Wed, 25 Aug 2021 22:44:48 +0200 Subject: [PATCH 01/14] Add option to save resized images w/o interlace. Add option to save images resized using PIL or ImageMagick as non-progressive. --- beets/util/artresizer.py | 33 +++++++++++++++++++++++++-------- 1 file changed, 25 insertions(+), 8 deletions(-) diff --git a/beets/util/artresizer.py b/beets/util/artresizer.py index bf6254c81..c00ed0489 100644 --- a/beets/util/artresizer.py +++ b/beets/util/artresizer.py @@ -64,7 +64,10 @@ def temp_file_for(path): return util.bytestring_path(f.name) -def pil_resize(maxwidth, path_in, path_out=None, quality=0, max_filesize=0): +def pil_resize( + maxwidth, path_in, path_out=None, + quality=0, max_filesize=0, deinterlace=False +): """Resize using Python Imaging Library (PIL). Return the output path of resized image. """ @@ -83,7 +86,12 @@ def pil_resize(maxwidth, path_in, path_out=None, quality=0, max_filesize=0): # Use PIL's default quality. quality = -1 - im.save(util.py3_path(path_out), quality=quality) + if not deinterlace: + im.save(util.py3_path(path_out), quality=quality) + else: + im.save(util.py3_path(path_out), quality=quality, + progressive=False) + if max_filesize > 0: # If maximum filesize is set, we attempt to lower the quality of # jpeg conversion by a proportional amount, up to 3 attempts @@ -105,9 +113,12 @@ def pil_resize(maxwidth, path_in, path_out=None, quality=0, max_filesize=0): if lower_qual < 10: lower_qual = 10 # Use optimize flag to improve filesize decrease - im.save( - util.py3_path(path_out), quality=lower_qual, optimize=True - ) + if not deinterlace: + im.save(util.py3_path(path_out), quality=lower_qual, + optimize=True) + else: + im.save(util.py3_path(path_out), quality=lower_qual, + optimize=True, progressive=False) log.warning(u"PIL Failed to resize file to below {0}B", max_filesize) return path_out @@ -120,7 +131,8 @@ def pil_resize(maxwidth, path_in, path_out=None, quality=0, max_filesize=0): return path_in -def im_resize(maxwidth, path_in, path_out=None, quality=0, max_filesize=0): +def im_resize(maxwidth, path_in, path_out=None, + quality=0, max_filesize=0, deinterlace=False): """Resize using ImageMagick. Use the ``magick`` program or ``convert`` on older versions. Return @@ -146,6 +158,9 @@ def im_resize(maxwidth, path_in, path_out=None, quality=0, max_filesize=0): if max_filesize > 0: cmd += ['-define', 'jpeg:extent={0}b'.format(max_filesize)] + if deinterlace: + cmd += ['-interlace', 'none'] + cmd.append(util.syspath(path_out, prefix=False)) try: @@ -243,7 +258,8 @@ class ArtResizer(six.with_metaclass(Shareable, object)): self.im_identify_cmd = ['magick', 'identify'] def resize( - self, maxwidth, path_in, path_out=None, quality=0, max_filesize=0 + self, maxwidth, path_in, path_out=None, + quality=0, max_filesize=0, deinterlace=False ): """Manipulate an image file according to the method, returning a new path. For PIL or IMAGEMAGIC methods, resizes the image to a @@ -253,7 +269,8 @@ class ArtResizer(six.with_metaclass(Shareable, object)): if self.local: func = BACKEND_FUNCS[self.method[0]] return func(maxwidth, path_in, path_out, - quality=quality, max_filesize=max_filesize) + quality=quality, max_filesize=max_filesize, + deinterlace=deinterlace) else: return path_in From cf31dbf6da2e999609e67d48eb537bacb355d9e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotrek=20Kocha=C5=84ski?= Date: Wed, 25 Aug 2021 22:54:50 +0200 Subject: [PATCH 02/14] Add function to convert images to non-progressive. --- beets/util/artresizer.py | 41 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/beets/util/artresizer.py b/beets/util/artresizer.py index c00ed0489..e91f31b47 100644 --- a/beets/util/artresizer.py +++ b/beets/util/artresizer.py @@ -216,6 +216,40 @@ BACKEND_GET_SIZE = { } +def pil_deinterlace(path_in, path_out=None): + path_out = path_out or temp_file_for(path_in) + from PIL import Image + + try: + im = Image.open(util.syspath(path_in)) + im.save(util.py3_path(path_out), progressive=False) + return path_out + except IOError: + return path_in + + +def im_deinterlace(path_in, path_out=None): + path_out = path_out or temp_file_for(path_in) + + cmd = ArtResizer.shared.im_convert_cmd + [ + util.syspath(path_in, prefix=False), + '-interlace', 'none', + util.syspath(path_out, prefix=False), + ] + + try: + util.command_output(cmd) + return path_out + except subprocess.CalledProcessError: + return path_in + + +DEINTERLACE_FUNCS = { + PIL: pil_deinterlace, + IMAGEMAGICK: im_deinterlace, +} + + class Shareable(type): """A pseudo-singleton metaclass that allows both shared and non-shared instances. The ``MyClass.shared`` property holds a @@ -274,6 +308,13 @@ class ArtResizer(six.with_metaclass(Shareable, object)): else: return path_in + def deinterlace(self, path_in, path_out=None): + if self.local: + func = DEINTERLACE_FUNCS[self.method[0]] + return func(path_in, path_out) + else: + return path_in + def proxy_url(self, maxwidth, url, quality=0): """Modifies an image URL according the method, returning a new URL. For WEBPROXY, a URL on the proxy server is returned. From c6e05e8ab70cb18861f2d5083fd1a0808b5e032e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotrek=20Kocha=C5=84ski?= Date: Wed, 25 Aug 2021 22:55:54 +0200 Subject: [PATCH 03/14] Add tests to check deinterlace functionality. --- test/test_art_resize.py | 43 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/test/test_art_resize.py b/test/test_art_resize.py index f7090d5e7..bdde0a1ce 100644 --- a/test/test_art_resize.py +++ b/test/test_art_resize.py @@ -23,12 +23,15 @@ import os from test import _common from test.helper import TestHelper -from beets.util import syspath +from beets.util import command_output, syspath from beets.util.artresizer import ( pil_resize, im_resize, get_im_version, get_pil_version, + pil_deinterlace, + im_deinterlace, + ArtResizer, ) @@ -90,6 +93,18 @@ class ArtResizerFileSizeTest(_common.TestCase, TestHelper): self.assertLess(os.stat(syspath(im_b)).st_size, os.stat(syspath(im_75_qual)).st_size) + # check if new deinterlace parameter breaks resize + im_di = resize_func( + 225, + self.IMG_225x225, + quality=95, + max_filesize=0, + deinterlace=True, + ) + # check valid path returned - deinterlace hasn't broken resize command + self.assertExists(im_di) + + @unittest.skipUnless(get_pil_version(), "PIL not available") def test_pil_file_resize(self): """Test PIL resize function is lowering file size.""" @@ -100,6 +115,32 @@ class ArtResizerFileSizeTest(_common.TestCase, TestHelper): """Test IM resize function is lowering file size.""" self._test_img_resize(im_resize) + @unittest.skipUnless(get_pil_version(), "PIL not available") + def test_pil_file_deinterlace(self): + """Test PIL deinterlace function. + + Check if pil_deinterlace function returns images + that are non-progressive + """ + path = pil_deinterlace(self.IMG_225x225) + from PIL import Image + with Image.open(path) as img: + self.assertFalse('progression' in img.info) + + @unittest.skipUnless(get_im_version(), "ImageMagick not available") + def test_im_file_deinterlace(self): + """Test ImageMagick deinterlace function. + + Check if im_deinterlace function returns images + that are non-progressive. + """ + path = im_deinterlace(self.IMG_225x225) + cmd = ArtResizer.shared.im_identify_cmd + [ + '-format', '%[interlace]', syspath(path, prefix=False), + ] + out = command_output(cmd).stdout + self.assertTrue(out == b'None') + def suite(): """Run this suite of tests.""" From 0a0719f9eddac773883f2fb239f1ca247b8c53eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotrek=20Kocha=C5=84ski?= Date: Wed, 25 Aug 2021 22:56:46 +0200 Subject: [PATCH 04/14] Add plugin option to store cover art non-progressive. --- beetsplug/fetchart.py | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/beetsplug/fetchart.py b/beetsplug/fetchart.py index 0a3254f53..d63970222 100644 --- a/beetsplug/fetchart.py +++ b/beetsplug/fetchart.py @@ -52,6 +52,7 @@ class Candidate(object): CANDIDATE_EXACT = 1 CANDIDATE_DOWNSCALE = 2 CANDIDATE_DOWNSIZE = 3 + CANDIDATE_DEINTERLACE = 4 MATCH_EXACT = 0 MATCH_FALLBACK = 1 @@ -80,7 +81,7 @@ class Candidate(object): return self.CANDIDATE_BAD if (not (plugin.enforce_ratio or plugin.minwidth or plugin.maxwidth - or plugin.max_filesize)): + or plugin.max_filesize or plugin.deinterlace)): return self.CANDIDATE_EXACT # get_size returns None if no local imaging backend is available @@ -147,6 +148,8 @@ class Candidate(object): return self.CANDIDATE_DOWNSCALE elif downsize: return self.CANDIDATE_DOWNSIZE + elif plugin.deinterlace: + return self.CANDIDATE_DEINTERLACE else: return self.CANDIDATE_EXACT @@ -159,13 +162,18 @@ class Candidate(object): self.path = \ ArtResizer.shared.resize(plugin.maxwidth, self.path, quality=plugin.quality, - max_filesize=plugin.max_filesize) + max_filesize=plugin.max_filesize, + deinterlace=plugin.deinterlace) elif self.check == self.CANDIDATE_DOWNSIZE: # dimensions are correct, so maxwidth is set to maximum dimension self.path = \ ArtResizer.shared.resize(max(self.size), self.path, quality=plugin.quality, - max_filesize=plugin.max_filesize) + max_filesize=plugin.max_filesize, + deinterlace=plugin.deinterlace) + elif self.check == self.CANDIDATE_DEINTERLACE: + self.path = \ + ArtResizer.shared.deinterlace(self.path) def _logged_get(log, *args, **kwargs): @@ -932,6 +940,7 @@ class FetchArtPlugin(plugins.BeetsPlugin, RequestMixin): 'lastfm_key': None, 'store_source': False, 'high_resolution': False, + 'deinterlace': False, }) self.config['google_key'].redact = True self.config['fanarttv_key'].redact = True @@ -949,6 +958,7 @@ class FetchArtPlugin(plugins.BeetsPlugin, RequestMixin): confuse.String(pattern=self.PAT_PERCENT)])) self.margin_px = None self.margin_percent = None + self.deinterlace = self.config['deinterlace'].get(bool) if type(self.enforce_ratio) is six.text_type: if self.enforce_ratio[-1] == u'%': self.margin_percent = float(self.enforce_ratio[:-1]) / 100 From 31d9c80e1875a3b4b64fc050f8b6deeaca225863 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotrek=20Kocha=C5=84ski?= Date: Wed, 25 Aug 2021 22:58:04 +0200 Subject: [PATCH 05/14] Update docs/ to reflect new option to deinterlace. Document new option to fetchart plugin to store cover art as non-progressive. --- docs/plugins/fetchart.rst | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/plugins/fetchart.rst b/docs/plugins/fetchart.rst index 6344c1562..8cefda9cd 100644 --- a/docs/plugins/fetchart.rst +++ b/docs/plugins/fetchart.rst @@ -86,8 +86,10 @@ file. The available options are: - **high_resolution**: If enabled, fetchart retrieves artwork in the highest resolution it can find (warning: image files can sometimes reach >20MB). Default: ``no``. +- **deinterlace**: If enabled, convert images to non-progressive/baseline. + Default: ``no``. -Note: ``maxwidth`` and ``enforce_ratio`` options require either `ImageMagick`_ +Note: ``maxwidth``, ``enforce_ratio`` and ``deinterlace`` options require either `ImageMagick`_ or `Pillow`_. .. note:: From 54522e6908e3c4f54b0199422412b6fc3fef62e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotrek=20Kocha=C5=84ski?= Date: Thu, 26 Aug 2021 13:18:15 +0200 Subject: [PATCH 06/14] Remove extraneous empty line that failed lint. --- test/test_art_resize.py | 1 - 1 file changed, 1 deletion(-) diff --git a/test/test_art_resize.py b/test/test_art_resize.py index bdde0a1ce..11175b5f7 100644 --- a/test/test_art_resize.py +++ b/test/test_art_resize.py @@ -104,7 +104,6 @@ class ArtResizerFileSizeTest(_common.TestCase, TestHelper): # check valid path returned - deinterlace hasn't broken resize command self.assertExists(im_di) - @unittest.skipUnless(get_pil_version(), "PIL not available") def test_pil_file_resize(self): """Test PIL resize function is lowering file size.""" From 7c1de83ef284755851cb44fbdaeffd9191658f49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotrek=20Kocha=C5=84ski?= Date: Thu, 26 Aug 2021 13:38:17 +0200 Subject: [PATCH 07/14] Extend fetchart documentation to cover new option. --- docs/plugins/fetchart.rst | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/docs/plugins/fetchart.rst b/docs/plugins/fetchart.rst index 8cefda9cd..2ee7c12a8 100644 --- a/docs/plugins/fetchart.rst +++ b/docs/plugins/fetchart.rst @@ -87,9 +87,12 @@ file. The available options are: resolution it can find (warning: image files can sometimes reach >20MB). Default: ``no``. - **deinterlace**: If enabled, convert images to non-progressive/baseline. +- **deinterlace**: If enabled, `Pillow`_ or `ImageMagick`_ backends are + instructed to store cover art as non-progressive. This might be preferred for + DAPs that don't support progressive images. Default: ``no``. -Note: ``maxwidth``, ``enforce_ratio`` and ``deinterlace`` options require either `ImageMagick`_ +Note: ``maxwidth`` and ``enforce_ratio`` options require either `ImageMagick`_ or `Pillow`_. .. note:: From 1a3ecc1ef41516a9fba2828bf62dbe19382d006b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotrek=20Kocha=C5=84ski?= Date: Thu, 26 Aug 2021 13:38:56 +0200 Subject: [PATCH 08/14] Add to changelog. --- docs/changelog.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/changelog.rst b/docs/changelog.rst index 0e1cc30a5..3c8d199dd 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -7,6 +7,10 @@ Changelog This release now requires Python 3.6 or later (it removes support for Python 2.7, 3.4, and 3.5). +* A new :doc:`/plugins/fetchart` option to store cover art as non-progressive + image. Useful for DAPs that support progressive images. Set ``deinterlace: + yes`` in your configuration to enable. + 1.5.0 (August 19, 2021) ----------------------- From bee4f13d8426e955e214d33a17d41f6d704e4820 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotrek=20Kocha=C5=84ski?= Date: Thu, 26 Aug 2021 14:43:37 +0200 Subject: [PATCH 09/14] Remove duplicate line. --- docs/plugins/fetchart.rst | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/plugins/fetchart.rst b/docs/plugins/fetchart.rst index 2ee7c12a8..3605ff27c 100644 --- a/docs/plugins/fetchart.rst +++ b/docs/plugins/fetchart.rst @@ -86,7 +86,6 @@ file. The available options are: - **high_resolution**: If enabled, fetchart retrieves artwork in the highest resolution it can find (warning: image files can sometimes reach >20MB). Default: ``no``. -- **deinterlace**: If enabled, convert images to non-progressive/baseline. - **deinterlace**: If enabled, `Pillow`_ or `ImageMagick`_ backends are instructed to store cover art as non-progressive. This might be preferred for DAPs that don't support progressive images. From 901377ded553989ca4b36811478b086dc6f8f58a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotrek=20Kocha=C5=84ski?= Date: Thu, 26 Aug 2021 15:01:37 +0200 Subject: [PATCH 10/14] Improve wording. --- docs/plugins/fetchart.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/plugins/fetchart.rst b/docs/plugins/fetchart.rst index 3605ff27c..5df6c6e34 100644 --- a/docs/plugins/fetchart.rst +++ b/docs/plugins/fetchart.rst @@ -87,8 +87,8 @@ file. The available options are: resolution it can find (warning: image files can sometimes reach >20MB). Default: ``no``. - **deinterlace**: If enabled, `Pillow`_ or `ImageMagick`_ backends are - instructed to store cover art as non-progressive. This might be preferred for - DAPs that don't support progressive images. + instructed to store cover art as non-progressive JPEG. You might need this if + you use DAPs that don't support progressive images. Default: ``no``. Note: ``maxwidth`` and ``enforce_ratio`` options require either `ImageMagick`_ From d30c8b32b52b6f06e6a43ee469d453b6a349a42e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotrek=20Kocha=C5=84ski?= Date: Thu, 26 Aug 2021 15:02:51 +0200 Subject: [PATCH 11/14] Remove unnecessary line break. --- beetsplug/fetchart.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/beetsplug/fetchart.py b/beetsplug/fetchart.py index d63970222..d6fff6316 100644 --- a/beetsplug/fetchart.py +++ b/beetsplug/fetchart.py @@ -172,8 +172,7 @@ class Candidate(object): max_filesize=plugin.max_filesize, deinterlace=plugin.deinterlace) elif self.check == self.CANDIDATE_DEINTERLACE: - self.path = \ - ArtResizer.shared.deinterlace(self.path) + self.path = ArtResizer.shared.deinterlace(self.path) def _logged_get(log, *args, **kwargs): From 1f6f0022c527246092b516668e519ad5aab1963d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotrek=20Kocha=C5=84ski?= Date: Tue, 31 Aug 2021 09:22:28 +0200 Subject: [PATCH 12/14] Remove unnecessary if-else As @ArsenArsen noted progressive defaults to false in the JPEG writer making the if-else pointless. --- beets/util/artresizer.py | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/beets/util/artresizer.py b/beets/util/artresizer.py index e91f31b47..f244e0820 100644 --- a/beets/util/artresizer.py +++ b/beets/util/artresizer.py @@ -86,11 +86,8 @@ def pil_resize( # Use PIL's default quality. quality = -1 - if not deinterlace: - im.save(util.py3_path(path_out), quality=quality) - else: - im.save(util.py3_path(path_out), quality=quality, - progressive=False) + im.save(util.py3_path(path_out), quality=quality, + progressive=not deinterlace) if max_filesize > 0: # If maximum filesize is set, we attempt to lower the quality of @@ -113,12 +110,8 @@ def pil_resize( if lower_qual < 10: lower_qual = 10 # Use optimize flag to improve filesize decrease - if not deinterlace: - im.save(util.py3_path(path_out), quality=lower_qual, - optimize=True) - else: - im.save(util.py3_path(path_out), quality=lower_qual, - optimize=True, progressive=False) + im.save(util.py3_path(path_out), quality=lower_qual, + optimize=True, progressive=not deinterlace) log.warning(u"PIL Failed to resize file to below {0}B", max_filesize) return path_out From 1a130059e8ef7e1ea613f3e1dd7dbedd802e33fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotrek=20Kocha=C5=84ski?= Date: Mon, 1 Nov 2021 13:51:57 +0100 Subject: [PATCH 13/14] `deinterlace` option to affect when no other processing remove interlacing by default when resizing/down-scaling, the `deinterlace` option is to remove interlace when otherwise no processing would have happened. --- beets/util/artresizer.py | 26 ++++++++++---------------- beetsplug/fetchart.py | 7 +++---- test/test_art_resize.py | 13 +------------ 3 files changed, 14 insertions(+), 32 deletions(-) diff --git a/beets/util/artresizer.py b/beets/util/artresizer.py index ad9f12f34..1ab689b04 100644 --- a/beets/util/artresizer.py +++ b/beets/util/artresizer.py @@ -58,10 +58,7 @@ def temp_file_for(path): return util.bytestring_path(f.name) -def pil_resize( - maxwidth, path_in, path_out=None, - quality=0, max_filesize=0, deinterlace=False -): +def pil_resize(maxwidth, path_in, path_out=None, quality=0, max_filesize=0): """Resize using Python Imaging Library (PIL). Return the output path of resized image. """ @@ -80,8 +77,9 @@ def pil_resize( # Use PIL's default quality. quality = -1 - im.save(util.py3_path(path_out), quality=quality, - progressive=not deinterlace) + # progressive=False only affects JPEG writter and is the default + # leaving for explicitness + im.save(util.py3_path(path_out), quality=quality, progressive=False) if max_filesize > 0: # If maximum filesize is set, we attempt to lower the quality of @@ -105,7 +103,7 @@ def pil_resize( lower_qual = 10 # Use optimize flag to improve filesize decrease im.save(util.py3_path(path_out), quality=lower_qual, - optimize=True, progressive=not deinterlace) + optimize=True, progressive=False) log.warning("PIL Failed to resize file to below {0}B", max_filesize) return path_out @@ -118,8 +116,7 @@ def pil_resize( return path_in -def im_resize(maxwidth, path_in, path_out=None, - quality=0, max_filesize=0, deinterlace=False): +def im_resize(maxwidth, path_in, path_out=None, quality=0, max_filesize=0): """Resize using ImageMagick. Use the ``magick`` program or ``convert`` on older versions. Return @@ -132,9 +129,11 @@ def im_resize(maxwidth, path_in, path_out=None, # "-resize WIDTHx>" shrinks images with the width larger # than the given width while maintaining the aspect ratio # with regards to the height. + # no interlace seems to be default, specify for explicitness cmd = ArtResizer.shared.im_convert_cmd + [ util.syspath(path_in, prefix=False), '-resize', f'{maxwidth}x>', + '-interlace', 'none', ] if quality > 0: @@ -145,9 +144,6 @@ def im_resize(maxwidth, path_in, path_out=None, if max_filesize > 0: cmd += ['-define', f'jpeg:extent={max_filesize}b'] - if deinterlace: - cmd += ['-interlace', 'none'] - cmd.append(util.syspath(path_out, prefix=False)) try: @@ -279,8 +275,7 @@ class ArtResizer(metaclass=Shareable): self.im_identify_cmd = ['magick', 'identify'] def resize( - self, maxwidth, path_in, path_out=None, - quality=0, max_filesize=0, deinterlace=False + self, maxwidth, path_in, path_out=None, quality=0, max_filesize=0 ): """Manipulate an image file according to the method, returning a new path. For PIL or IMAGEMAGIC methods, resizes the image to a @@ -290,8 +285,7 @@ class ArtResizer(metaclass=Shareable): if self.local: func = BACKEND_FUNCS[self.method[0]] return func(maxwidth, path_in, path_out, - quality=quality, max_filesize=max_filesize, - deinterlace=deinterlace) + quality=quality, max_filesize=max_filesize) else: return path_in diff --git a/beetsplug/fetchart.py b/beetsplug/fetchart.py index 0cef77210..574e8dae1 100644 --- a/beetsplug/fetchart.py +++ b/beetsplug/fetchart.py @@ -73,6 +73,7 @@ class Candidate: Return `CANDIDATE_DOWNSCALE` if the file must be rescaled. Return `CANDIDATE_DOWNSIZE` if the file must be resized, and possibly also rescaled. + Return `CANDIDATE_DEINTERLACE` if the file must be deinterlaced. """ if not self.path: return self.CANDIDATE_BAD @@ -159,15 +160,13 @@ class Candidate: self.path = \ ArtResizer.shared.resize(plugin.maxwidth, self.path, quality=plugin.quality, - max_filesize=plugin.max_filesize, - deinterlace=plugin.deinterlace) + max_filesize=plugin.max_filesize) elif self.check == self.CANDIDATE_DOWNSIZE: # dimensions are correct, so maxwidth is set to maximum dimension self.path = \ ArtResizer.shared.resize(max(self.size), self.path, quality=plugin.quality, - max_filesize=plugin.max_filesize, - deinterlace=plugin.deinterlace) + max_filesize=plugin.max_filesize) elif self.check == self.CANDIDATE_DEINTERLACE: self.path = ArtResizer.shared.deinterlace(self.path) diff --git a/test/test_art_resize.py b/test/test_art_resize.py index 9bc8f2eff..73847e0a6 100644 --- a/test/test_art_resize.py +++ b/test/test_art_resize.py @@ -90,17 +90,6 @@ class ArtResizerFileSizeTest(_common.TestCase, TestHelper): self.assertLess(os.stat(syspath(im_b)).st_size, os.stat(syspath(im_75_qual)).st_size) - # check if new deinterlace parameter breaks resize - im_di = resize_func( - 225, - self.IMG_225x225, - quality=95, - max_filesize=0, - deinterlace=True, - ) - # check valid path returned - deinterlace hasn't broken resize command - self.assertExists(im_di) - @unittest.skipUnless(get_pil_version(), "PIL not available") def test_pil_file_resize(self): """Test PIL resize function is lowering file size.""" @@ -135,7 +124,7 @@ class ArtResizerFileSizeTest(_common.TestCase, TestHelper): '-format', '%[interlace]', syspath(path, prefix=False), ] out = command_output(cmd).stdout - self.assertTrue(out == 'None') + self.assertTrue(out == b'None') def suite(): From fbc2862ff06a4948364afe7a366516b51a98af8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotrek=20Kocha=C5=84ski?= Date: Mon, 1 Nov 2021 18:35:45 +0100 Subject: [PATCH 14/14] Improve style and clarity of comments --- beets/util/artresizer.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/beets/util/artresizer.py b/beets/util/artresizer.py index 1ab689b04..f9381f6c4 100644 --- a/beets/util/artresizer.py +++ b/beets/util/artresizer.py @@ -77,8 +77,8 @@ def pil_resize(maxwidth, path_in, path_out=None, quality=0, max_filesize=0): # Use PIL's default quality. quality = -1 - # progressive=False only affects JPEG writter and is the default - # leaving for explicitness + # progressive=False only affects JPEGs and is the default, + # but we include it here for explicitness. im.save(util.py3_path(path_out), quality=quality, progressive=False) if max_filesize > 0: @@ -129,7 +129,8 @@ def im_resize(maxwidth, path_in, path_out=None, quality=0, max_filesize=0): # "-resize WIDTHx>" shrinks images with the width larger # than the given width while maintaining the aspect ratio # with regards to the height. - # no interlace seems to be default, specify for explicitness + # ImageMagick already seems to default to no interlace, but we include it + # here for the sake of explicitness. cmd = ArtResizer.shared.im_convert_cmd + [ util.syspath(path_in, prefix=False), '-resize', f'{maxwidth}x>',