mirror of
https://github.com/fergalmoran/picard.git
synced 2025-12-22 09:18:18 +00:00
281 lines
11 KiB
Python
281 lines
11 KiB
Python
# -*- coding: utf-8 -*-
|
|
#
|
|
# Picard, the next-generation MusicBrainz tagger
|
|
#
|
|
# Copyright (C) 2024 Giorgio Fontanive
|
|
#
|
|
# This program is free software; you can redistribute it and/or
|
|
# modify it under the terms of the GNU General Public License
|
|
# as published by the Free Software Foundation; either version 2
|
|
# of the License, or (at your option) any later version.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with this program; if not, write to the Free Software
|
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
|
|
from copy import copy
|
|
|
|
from PyQt6.QtCore import QBuffer
|
|
from PyQt6.QtGui import QImage
|
|
|
|
from test.picardtestcase import PicardTestCase
|
|
|
|
from picard import config
|
|
from picard.coverart.image import CoverArtImage
|
|
from picard.coverart.processing import run_image_processors
|
|
from picard.coverart.processing.filters import (
|
|
size_filter,
|
|
size_metadata_filter,
|
|
)
|
|
from picard.coverart.processing.processors import ResizeImage
|
|
from picard.extension_points.cover_art_processors import (
|
|
CoverArtProcessingError,
|
|
ProcessingImage,
|
|
ProcessingTarget,
|
|
)
|
|
|
|
|
|
def create_fake_image(width, height, image_format):
|
|
buffer = QBuffer()
|
|
image = QImage(width, height, QImage.Format.Format_ARGB32)
|
|
image.save(buffer, image_format)
|
|
buffer.close()
|
|
return buffer.data()
|
|
|
|
|
|
class ImageFiltersTest(PicardTestCase):
|
|
def setUp(self):
|
|
super().setUp()
|
|
settings = {
|
|
'filter_cover_by_size': True,
|
|
'cover_minimum_width': 500,
|
|
'cover_minimum_height': 500
|
|
}
|
|
self.set_config_values(settings)
|
|
|
|
def test_filter_by_size(self):
|
|
image1 = create_fake_image(400, 600, "png")
|
|
image2 = create_fake_image(500, 500, "jpeg")
|
|
image3 = create_fake_image(600, 600, "bmp")
|
|
self.assertFalse(size_filter(image1))
|
|
self.assertTrue(size_filter(image2))
|
|
self.assertTrue(size_filter(image3))
|
|
|
|
def test_filter_by_size_metadata(self):
|
|
image_metadata1 = {'width': 400, 'height': 600}
|
|
image_metadata2 = {'width': 500, 'height': 500}
|
|
image_metadata3 = {'width': 600, 'height': 600}
|
|
self.assertFalse(size_metadata_filter(image_metadata1))
|
|
self.assertTrue(size_metadata_filter(image_metadata2))
|
|
self.assertTrue(size_metadata_filter(image_metadata3))
|
|
|
|
|
|
class ImageProcessorsTest(PicardTestCase):
|
|
def setUp(self):
|
|
super().setUp()
|
|
self.settings = {
|
|
'enabled_plugins': [],
|
|
'cover_tags_scale_up': True,
|
|
'cover_tags_scale_down': True,
|
|
'cover_tags_resize_use_width': True,
|
|
'cover_tags_resize_target_width': 500,
|
|
'cover_tags_resize_use_height': True,
|
|
'cover_tags_resize_target_height': 500,
|
|
'cover_tags_stretch': False,
|
|
'cover_tags_crop': False,
|
|
'cover_file_scale_up': True,
|
|
'cover_file_scale_down': True,
|
|
'cover_file_resize_use_width': True,
|
|
'cover_file_resize_target_width': 750,
|
|
'cover_file_resize_use_height': True,
|
|
'cover_file_resize_target_height': 750,
|
|
'cover_file_stretch': False,
|
|
'cover_file_crop': False,
|
|
'save_images_to_tags': True,
|
|
'save_images_to_files': True,
|
|
}
|
|
|
|
def _check_image_processors(self, size, expected_tags_size, expected_file_size=None):
|
|
coverartimage = CoverArtImage()
|
|
image = create_fake_image(size[0], size[1], "jpg")
|
|
run_image_processors(image, coverartimage)
|
|
tags_size = (coverartimage.width, coverartimage.height)
|
|
if config.setting['save_images_to_tags']:
|
|
self.assertEqual(tags_size, expected_tags_size)
|
|
else:
|
|
self.assertEqual(tags_size, size)
|
|
if config.setting['save_images_to_files']:
|
|
external_cover = coverartimage.external_file_coverart
|
|
file_size = (external_cover.width, external_cover.height)
|
|
self.assertEqual(file_size, expected_file_size)
|
|
else:
|
|
self.assertIsNone(coverartimage.external_file_coverart)
|
|
extension = coverartimage.extension[1:]
|
|
self.assertEqual(extension, "jpg")
|
|
|
|
def test_image_processors_save_to_both(self):
|
|
self.set_config_values(self.settings)
|
|
self._check_image_processors((1000, 1000), (500, 500), (750, 750))
|
|
self._check_image_processors((600, 600), (500, 500), (750, 750))
|
|
self._check_image_processors((400, 400), (500, 500), (750, 750))
|
|
|
|
def test_image_processors_save_to_tags(self):
|
|
settings = copy(self.settings)
|
|
settings['save_images_to_files'] = False
|
|
self.set_config_values(settings)
|
|
self._check_image_processors((1000, 1000), (500, 500))
|
|
self._check_image_processors((600, 600), (500, 500))
|
|
self._check_image_processors((400, 400), (500, 500))
|
|
self.set_config_values(self.settings)
|
|
|
|
def test_image_processors_save_to_file(self):
|
|
settings = copy(self.settings)
|
|
settings['save_images_to_tags'] = False
|
|
self.set_config_values(settings)
|
|
self._check_image_processors((1000, 1000), (1000, 1000), (750, 750))
|
|
self._check_image_processors((600, 600), (600, 600), (750, 750))
|
|
self._check_image_processors((400, 400), (400, 400), (750, 750))
|
|
self.set_config_values(self.settings)
|
|
|
|
def test_image_processors_save_to_none(self):
|
|
settings = copy(self.settings)
|
|
settings['save_images_to_tags'] = False
|
|
settings['save_images_to_files'] = False
|
|
self.set_config_values(settings)
|
|
self._check_image_processors((1000, 1000), (1000, 1000), (1000, 1000))
|
|
self.set_config_values(self.settings)
|
|
|
|
def _check_resize_image(self, size, expected_size):
|
|
image = ProcessingImage(create_fake_image(size[0], size[1], "jpg"))
|
|
processor = ResizeImage()
|
|
processor.run(image, ProcessingTarget.TAGS)
|
|
new_size = (image.get_result().width(), image.get_result().height())
|
|
new_info_size = (image.info.width, image.info.height)
|
|
self.assertEqual(new_size, expected_size)
|
|
self.assertEqual(new_info_size, expected_size)
|
|
|
|
def test_scale_down_both_dimensions(self):
|
|
self.set_config_values(self.settings)
|
|
self._check_resize_image((1000, 1000), (500, 500))
|
|
self._check_resize_image((1000, 500), (500, 250))
|
|
self._check_resize_image((600, 1200), (250, 500))
|
|
|
|
def test_scale_down_only_width(self):
|
|
settings = copy(self.settings)
|
|
settings["cover_tags_resize_use_height"] = False
|
|
self.set_config_values(settings)
|
|
self._check_resize_image((1000, 1000), (500, 500))
|
|
self._check_resize_image((1000, 500), (500, 250))
|
|
self._check_resize_image((600, 1200), (500, 1000))
|
|
self.set_config_values(self.settings)
|
|
|
|
def test_scale_down_only_height(self):
|
|
settings = copy(self.settings)
|
|
settings["cover_tags_resize_use_width"] = False
|
|
self.set_config_values(settings)
|
|
self._check_resize_image((1000, 1000), (500, 500))
|
|
self._check_resize_image((1000, 500), (1000, 500))
|
|
self._check_resize_image((600, 1200), (250, 500))
|
|
self.set_config_values(self.settings)
|
|
|
|
def test_scale_up_both_dimensions(self):
|
|
self.set_config_values(self.settings)
|
|
self._check_resize_image((250, 250), (500, 500))
|
|
self._check_resize_image((400, 500), (400, 500))
|
|
self._check_resize_image((250, 150), (500, 300))
|
|
|
|
def test_scale_up_only_width(self):
|
|
settings = copy(self.settings)
|
|
settings["cover_tags_resize_use_height"] = False
|
|
self.set_config_values(settings)
|
|
self._check_resize_image((250, 250), (500, 500))
|
|
self._check_resize_image((400, 500), (500, 625))
|
|
self._check_resize_image((500, 250), (500, 250))
|
|
self.set_config_values(self.settings)
|
|
|
|
def test_scale_up_only_height(self):
|
|
settings = copy(self.settings)
|
|
settings["cover_tags_resize_use_width"] = False
|
|
self.set_config_values(settings)
|
|
self._check_resize_image((250, 250), (500, 500))
|
|
self._check_resize_image((400, 500), (400, 500))
|
|
self._check_resize_image((500, 250), (1000, 500))
|
|
self.set_config_values(self.settings)
|
|
|
|
def test_scale_priority(self):
|
|
settings = copy(self.settings)
|
|
settings["cover_tags_resize_target_width"] = 500
|
|
settings["cover_tags_resize_target_height"] = 1000
|
|
self.set_config_values(settings)
|
|
self._check_resize_image((750, 750), (500, 500))
|
|
self.set_config_values(self.settings)
|
|
|
|
def test_stretch_both_dimensions(self):
|
|
settings = copy(self.settings)
|
|
settings["cover_tags_stretch"] = True
|
|
self.set_config_values(settings)
|
|
self._check_resize_image((1000, 100), (500, 500))
|
|
self._check_resize_image((200, 500), (500, 500))
|
|
self._check_resize_image((200, 2000), (500, 500))
|
|
self.set_config_values(self.settings)
|
|
|
|
def test_stretch_only_width(self):
|
|
settings = copy(self.settings)
|
|
settings["cover_tags_stretch"] = True
|
|
settings["cover_tags_resize_use_height"] = False
|
|
self.set_config_values(settings)
|
|
self._check_resize_image((1000, 100), (500, 100))
|
|
self._check_resize_image((200, 500), (500, 500))
|
|
self._check_resize_image((200, 2000), (500, 2000))
|
|
self.set_config_values(self.settings)
|
|
|
|
def test_stretch_only_height(self):
|
|
settings = copy(self.settings)
|
|
settings["cover_tags_stretch"] = True
|
|
settings["cover_tags_resize_use_width"] = False
|
|
self.set_config_values(settings)
|
|
self._check_resize_image((1000, 100), (1000, 500))
|
|
self._check_resize_image((200, 500), (200, 500))
|
|
self._check_resize_image((200, 2000), (200, 500))
|
|
self.set_config_values(self.settings)
|
|
|
|
def test_crop_both_dimensions(self):
|
|
settings = copy(self.settings)
|
|
settings["cover_tags_crop"] = True
|
|
self.set_config_values(settings)
|
|
self._check_resize_image((1000, 100), (500, 500))
|
|
self._check_resize_image((750, 1000), (500, 500))
|
|
self._check_resize_image((250, 1000), (500, 500))
|
|
self.set_config_values(self.settings)
|
|
|
|
def test_crop_only_width(self):
|
|
settings = copy(self.settings)
|
|
settings["cover_tags_crop"] = True
|
|
settings["cover_tags_resize_use_height"] = False
|
|
self.set_config_values(settings)
|
|
self._check_resize_image((1000, 100), (500, 100))
|
|
self._check_resize_image((750, 1000), (500, 1000))
|
|
self._check_resize_image((250, 1000), (500, 1000))
|
|
self.set_config_values(self.settings)
|
|
|
|
def test_crop_only_height(self):
|
|
settings = copy(self.settings)
|
|
settings["cover_tags_crop"] = True
|
|
settings["cover_tags_resize_use_width"] = False
|
|
self.set_config_values(settings)
|
|
self._check_resize_image((1000, 100), (1000, 500))
|
|
self._check_resize_image((750, 1000), (750, 500))
|
|
self._check_resize_image((250, 1000), (250, 500))
|
|
self.set_config_values(self.settings)
|
|
|
|
def test_identification_error(self):
|
|
image = create_fake_image(0, 0, "jpg")
|
|
coverartimage = CoverArtImage()
|
|
with self.assertRaises(CoverArtProcessingError):
|
|
run_image_processors(image, coverartimage)
|