mirror of
https://github.com/fergalmoran/picard.git
synced 2026-01-06 16:44:06 +00:00
Add scale to width and scale to height resize modes
This commit is contained in:
@@ -20,10 +20,19 @@
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
from collections import namedtuple
|
||||
from enum import IntEnum
|
||||
|
||||
from picard.i18n import N_
|
||||
|
||||
|
||||
class ResizeModes(IntEnum):
|
||||
MAINTAIN_ASPECT_RATIO = 0,
|
||||
SCALE_TO_WIDTH = 1,
|
||||
SCALE_TO_HEIGHT = 2,
|
||||
CROP_TO_FIT = 3,
|
||||
STRETCH_TO_FIT = 4
|
||||
|
||||
|
||||
CoverResizeMode = namedtuple('CoverResizeMode', ['mode', 'title', 'tooltip'])
|
||||
|
||||
COVER_RESIZE_MODES = [
|
||||
@@ -32,7 +41,7 @@ COVER_RESIZE_MODES = [
|
||||
# different from the order of appearance in the combo box. This will
|
||||
# allow modes to be added or removed and re-ordered if required.
|
||||
|
||||
CoverResizeMode(0, N_('Maintain aspect ratio'), N_(
|
||||
CoverResizeMode(ResizeModes.MAINTAIN_ASPECT_RATIO, N_('Maintain aspect ratio'), N_(
|
||||
"<p>"
|
||||
"Scale the source image so that it fits within the target dimensions."
|
||||
"</p><p>"
|
||||
@@ -44,7 +53,25 @@ COVER_RESIZE_MODES = [
|
||||
"</p>"
|
||||
)),
|
||||
|
||||
CoverResizeMode(1, N_('Crop to fit'), N_(
|
||||
CoverResizeMode(ResizeModes.SCALE_TO_WIDTH, N_('Scale to width'), N_(
|
||||
"<p>"
|
||||
"Scale the width of the source image to the target width while keeping aspect ratio."
|
||||
"</p><p>"
|
||||
"For example, a 2000x1000 image resized to a target width of "
|
||||
"1000 would result in a final image size of 1000x500."
|
||||
"</p>"
|
||||
)),
|
||||
|
||||
CoverResizeMode(ResizeModes.SCALE_TO_HEIGHT, N_('Scale to height'), N_(
|
||||
"<p>"
|
||||
"Scale the height of the source image to the target height while keeping aspect ratio."
|
||||
"</p><p>"
|
||||
"For example, a 1000x2000 image resized to a target height of "
|
||||
"1000 would result in a final image size of 500x1000."
|
||||
"</p>"
|
||||
)),
|
||||
|
||||
CoverResizeMode(ResizeModes.CROP_TO_FIT, N_('Crop to fit'), N_(
|
||||
"<p>"
|
||||
"Scale the source image so that it completely fills the target dimensions "
|
||||
"in both directions."
|
||||
@@ -58,7 +85,7 @@ COVER_RESIZE_MODES = [
|
||||
"</p>"
|
||||
)),
|
||||
|
||||
CoverResizeMode(2, N_('Stretch to fit'), N_(
|
||||
CoverResizeMode(ResizeModes.STRETCH_TO_FIT, N_('Stretch to fit'), N_(
|
||||
"<p>"
|
||||
"Stretch the image to exactly fit the specified dimensions, "
|
||||
"distorting it if necessary."
|
||||
|
||||
@@ -24,6 +24,7 @@ from PyQt6.QtCore import Qt
|
||||
|
||||
from picard import log
|
||||
from picard.config import get_config
|
||||
from picard.const.cover_processing import ResizeModes
|
||||
from picard.extension_points.cover_art_processors import (
|
||||
ImageProcessor,
|
||||
ProcessingTarget,
|
||||
@@ -44,71 +45,51 @@ class ResizeImage(ImageProcessor):
|
||||
def same_processing(self):
|
||||
setting = get_config().setting
|
||||
both_resize = setting['cover_tags_resize'] and setting['cover_file_resize']
|
||||
same_enlarge = setting['cover_tags_dont_enlarge'] == setting['cover_file_dont_enlarge']
|
||||
tags_size = (
|
||||
setting['cover_tags_resize_target_width'] if setting['cover_tags_resize_use_width'] else 0,
|
||||
setting['cover_tags_resize_target_height'] if setting['cover_tags_resize_use_height'] else 0
|
||||
)
|
||||
file_size = (
|
||||
setting['cover_file_resize_target_width'] if setting['cover_file_resize_use_width'] else 0,
|
||||
setting['cover_file_resize_target_height'] if setting['cover_file_resize_use_height'] else 0
|
||||
)
|
||||
same_size = tags_size == file_size
|
||||
same_enlarge = setting['cover_tags_enlarge'] == setting['cover_file_enlarge']
|
||||
same_width = setting['cover_tags_resize_target_width'] == setting['cover_file_resize_target_width']
|
||||
same_height = setting['cover_tags_resize_target_height'] == setting['cover_file_resize_target_height']
|
||||
same_resize_mode = setting['cover_tags_resize_mode'] == setting['cover_file_resize_mode']
|
||||
return both_resize and same_enlarge and same_size and same_resize_mode
|
||||
return both_resize and same_enlarge and same_width and same_height and same_resize_mode
|
||||
|
||||
def run(self, image, target):
|
||||
start_time = time.time()
|
||||
config = get_config()
|
||||
if target == ProcessingTarget.TAGS:
|
||||
scale_up = not config.setting['cover_tags_dont_enlarge']
|
||||
use_width = config.setting['cover_tags_resize_use_width']
|
||||
scale_up = config.setting['cover_tags_enlarge']
|
||||
target_width = config.setting['cover_tags_resize_target_width']
|
||||
use_height = config.setting['cover_tags_resize_use_height']
|
||||
target_height = config.setting['cover_tags_resize_target_height']
|
||||
crop = config.setting['cover_tags_resize_mode'] == 1
|
||||
stretch = config.setting['cover_tags_resize_mode'] == 2
|
||||
resize_mode = config.setting['cover_tags_resize_mode']
|
||||
else:
|
||||
scale_up = not config.setting['cover_file_dont_enlarge']
|
||||
use_width = config.setting['cover_file_resize_use_width']
|
||||
scale_up = config.setting['cover_file_enlarge']
|
||||
target_width = config.setting['cover_file_resize_target_width']
|
||||
use_height = config.setting['cover_file_resize_use_height']
|
||||
target_height = config.setting['cover_file_resize_target_height']
|
||||
crop = config.setting['cover_file_resize_mode'] == 1
|
||||
stretch = config.setting['cover_file_resize_mode'] == 2
|
||||
resize_mode = config.setting['cover_file_resize_mode']
|
||||
|
||||
width_resize = target_width if use_width else image.info.width
|
||||
height_resize = target_height if use_height else image.info.height
|
||||
width_scale_factor = width_resize / image.info.width
|
||||
height_scale_factor = height_resize / image.info.height
|
||||
use_both_dimensions = use_height and use_width
|
||||
if use_both_dimensions and not stretch:
|
||||
if crop:
|
||||
scale_factor = max(width_scale_factor, height_scale_factor)
|
||||
else:
|
||||
scale_factor = min(width_scale_factor, height_scale_factor)
|
||||
width_scale_factor = scale_factor
|
||||
height_scale_factor = scale_factor
|
||||
if (width_scale_factor == 1 and height_scale_factor == 1
|
||||
or ((width_scale_factor > 1 or height_scale_factor > 1) and not scale_up)):
|
||||
width_scale_factor = target_width / image.info.width
|
||||
height_scale_factor = target_height / image.info.height
|
||||
if resize_mode == ResizeModes.MAINTAIN_ASPECT_RATIO:
|
||||
scale_factor = min(width_scale_factor, height_scale_factor)
|
||||
elif resize_mode == ResizeModes.SCALE_TO_WIDTH:
|
||||
scale_factor = width_scale_factor
|
||||
elif resize_mode == ResizeModes.SCALE_TO_HEIGHT:
|
||||
scale_factor = height_scale_factor
|
||||
else: # crop or stretch
|
||||
scale_factor = max(width_scale_factor, height_scale_factor)
|
||||
if scale_factor == 1 or scale_factor > 1 and not scale_up:
|
||||
# no resizing needed
|
||||
return
|
||||
|
||||
qimage = image.get_qimage()
|
||||
if stretch:
|
||||
scaled_image = qimage.scaled(width_resize, height_resize, Qt.AspectRatioMode.IgnoreAspectRatio)
|
||||
elif crop:
|
||||
scaled_image = qimage.scaled(width_resize, height_resize, Qt.AspectRatioMode.KeepAspectRatioByExpanding)
|
||||
cutoff_width = (scaled_image.width() - width_resize) // 2
|
||||
cutoff_height = (scaled_image.height() - height_resize) // 2
|
||||
scaled_image = scaled_image.copy(cutoff_width, cutoff_height, width_resize, height_resize)
|
||||
else: # keep aspect ratio
|
||||
if use_both_dimensions:
|
||||
scaled_image = qimage.scaled(width_resize, height_resize, Qt.AspectRatioMode.KeepAspectRatio)
|
||||
elif use_width:
|
||||
scaled_image = qimage.scaledToWidth(width_resize)
|
||||
else:
|
||||
scaled_image = qimage.scaledToHeight(height_resize)
|
||||
new_width = image.info.width * scale_factor
|
||||
new_height = image.info.height * scale_factor
|
||||
if resize_mode == ResizeModes.STRETCH_TO_FIT:
|
||||
new_width = image.info.width * width_scale_factor
|
||||
new_height = image.info.height * height_scale_factor
|
||||
scaled_image = qimage.scaled(int(new_width), int(new_height), Qt.AspectRatioMode.IgnoreAspectRatio)
|
||||
if resize_mode == ResizeModes.CROP_TO_FIT:
|
||||
cutoff_width = (scaled_image.width() - target_width) // 2
|
||||
cutoff_height = (scaled_image.height() - target_height) // 2
|
||||
scaled_image = scaled_image.copy(cutoff_width, cutoff_height, target_width, target_height)
|
||||
|
||||
log.debug(
|
||||
"Resized cover art from %d x %d to %d x %d in %.2f ms",
|
||||
|
||||
@@ -177,20 +177,16 @@ BoolOption('setting', 'save_only_one_front_image', False, title=N_("Save only a
|
||||
BoolOption('setting', 'filter_cover_by_size', False)
|
||||
IntOption('setting', 'cover_minimum_width', DEFAULT_COVER_MIN_SIZE)
|
||||
IntOption('setting', 'cover_minimum_height', DEFAULT_COVER_MIN_SIZE)
|
||||
BoolOption('setting', 'cover_tags_dont_enlarge', True)
|
||||
BoolOption('setting', 'cover_tags_enlarge', False)
|
||||
BoolOption('setting', 'cover_tags_resize', False)
|
||||
BoolOption('setting', 'cover_tags_resize_use_width', True)
|
||||
IntOption('setting', 'cover_tags_resize_target_width', DEFAULT_COVER_MAX_SIZE)
|
||||
BoolOption('setting', 'cover_tags_resize_use_height', True)
|
||||
IntOption('setting', 'cover_tags_resize_target_height', DEFAULT_COVER_MAX_SIZE)
|
||||
IntOption('setting', 'cover_tags_resize_mode', DEFAULT_COVER_RESIZE_MODE)
|
||||
BoolOption('setting', 'cover_tags_convert_images', False)
|
||||
TextOption('setting', 'cover_tags_convert_to_format', DEFAULT_COVER_CONVERTING_FORMAT)
|
||||
BoolOption('setting', 'cover_file_dont_enlarge', True)
|
||||
BoolOption('setting', 'cover_file_enlarge', False)
|
||||
BoolOption('setting', 'cover_file_resize', False)
|
||||
BoolOption('setting', 'cover_file_resize_use_width', True)
|
||||
IntOption('setting', 'cover_file_resize_target_width', DEFAULT_COVER_MAX_SIZE)
|
||||
BoolOption('setting', 'cover_file_resize_use_height', True)
|
||||
IntOption('setting', 'cover_file_resize_target_height', DEFAULT_COVER_MAX_SIZE)
|
||||
IntOption('setting', 'cover_file_resize_mode', DEFAULT_COVER_RESIZE_MODE)
|
||||
BoolOption('setting', 'cover_file_convert_images', False)
|
||||
|
||||
@@ -17,7 +17,7 @@ from picard.i18n import gettext as _
|
||||
class Ui_CoverProcessingOptionsPage(object):
|
||||
def setupUi(self, CoverProcessingOptionsPage):
|
||||
CoverProcessingOptionsPage.setObjectName("CoverProcessingOptionsPage")
|
||||
CoverProcessingOptionsPage.resize(535, 467)
|
||||
CoverProcessingOptionsPage.resize(535, 475)
|
||||
self.verticalLayout = QtWidgets.QVBoxLayout(CoverProcessingOptionsPage)
|
||||
self.verticalLayout.setObjectName("verticalLayout")
|
||||
self.filtering = QtWidgets.QGroupBox(parent=CoverProcessingOptionsPage)
|
||||
@@ -102,7 +102,7 @@ class Ui_CoverProcessingOptionsPage(object):
|
||||
self.horizontalLayout_5.setContentsMargins(0, 0, 0, 0)
|
||||
self.horizontalLayout_5.setSpacing(4)
|
||||
self.horizontalLayout_5.setObjectName("horizontalLayout_5")
|
||||
self.tags_resize_width_label = QtWidgets.QCheckBox(parent=self.tags_resize_width_widget)
|
||||
self.tags_resize_width_label = QtWidgets.QLabel(parent=self.tags_resize_width_widget)
|
||||
self.tags_resize_width_label.setObjectName("tags_resize_width_label")
|
||||
self.horizontalLayout_5.addWidget(self.tags_resize_width_label)
|
||||
self.tags_resize_width_value = QtWidgets.QSpinBox(parent=self.tags_resize_width_widget)
|
||||
@@ -130,7 +130,7 @@ class Ui_CoverProcessingOptionsPage(object):
|
||||
self.horizontalLayout_3.setContentsMargins(0, 0, 0, 0)
|
||||
self.horizontalLayout_3.setSpacing(4)
|
||||
self.horizontalLayout_3.setObjectName("horizontalLayout_3")
|
||||
self.tags_resize_height_label = QtWidgets.QCheckBox(parent=self.tags_resize_height_widget)
|
||||
self.tags_resize_height_label = QtWidgets.QLabel(parent=self.tags_resize_height_widget)
|
||||
self.tags_resize_height_label.setObjectName("tags_resize_height_label")
|
||||
self.horizontalLayout_3.addWidget(self.tags_resize_height_label)
|
||||
self.tags_resize_height_value = QtWidgets.QSpinBox(parent=self.tags_resize_height_widget)
|
||||
@@ -176,7 +176,7 @@ class Ui_CoverProcessingOptionsPage(object):
|
||||
self.horizontalLayout_6.setContentsMargins(0, 0, 0, 0)
|
||||
self.horizontalLayout_6.setSpacing(4)
|
||||
self.horizontalLayout_6.setObjectName("horizontalLayout_6")
|
||||
self.file_resize_width_label = QtWidgets.QCheckBox(parent=self.file_resize_width_widget)
|
||||
self.file_resize_width_label = QtWidgets.QLabel(parent=self.file_resize_width_widget)
|
||||
self.file_resize_width_label.setObjectName("file_resize_width_label")
|
||||
self.horizontalLayout_6.addWidget(self.file_resize_width_label)
|
||||
self.file_resize_width_value = QtWidgets.QSpinBox(parent=self.file_resize_width_widget)
|
||||
@@ -204,7 +204,7 @@ class Ui_CoverProcessingOptionsPage(object):
|
||||
self.horizontalLayout_4.setContentsMargins(0, 0, 0, 0)
|
||||
self.horizontalLayout_4.setSpacing(4)
|
||||
self.horizontalLayout_4.setObjectName("horizontalLayout_4")
|
||||
self.file_resize_height_label = QtWidgets.QCheckBox(parent=self.file_resize_height_widget)
|
||||
self.file_resize_height_label = QtWidgets.QLabel(parent=self.file_resize_height_widget)
|
||||
self.file_resize_height_label.setObjectName("file_resize_height_label")
|
||||
self.horizontalLayout_4.addWidget(self.file_resize_height_label)
|
||||
self.file_resize_height_value = QtWidgets.QSpinBox(parent=self.file_resize_height_widget)
|
||||
@@ -277,17 +277,17 @@ class Ui_CoverProcessingOptionsPage(object):
|
||||
self.px_label2.setText(_("px"))
|
||||
self.resizing.setTitle(_("Resize images to the given size"))
|
||||
self.tags_scale_down.setTitle(_("Resize images saved to tags "))
|
||||
self.tags_resize_width_label.setText(_("Width:"))
|
||||
self.tags_resize_width_label.setText(_("Maximum width:"))
|
||||
self.px_label5.setText(_("px"))
|
||||
self.tags_resize_height_label.setText(_("Height:"))
|
||||
self.tags_resize_height_label.setText(_("Maximum height:"))
|
||||
self.px_label6.setText(_("px"))
|
||||
self.tags_scale_up.setText(_("Don\'t enlarge"))
|
||||
self.tags_scale_up.setText(_("Enlarge"))
|
||||
self.file_scale_down.setTitle(_("Resize images saved to files"))
|
||||
self.file_resize_width_label.setText(_("Width:"))
|
||||
self.file_resize_width_label.setText(_("Maximum width:"))
|
||||
self.px_label3.setText(_("px"))
|
||||
self.file_resize_height_label.setText(_("Height:"))
|
||||
self.file_resize_height_label.setText(_("Maximum height:"))
|
||||
self.px_label4.setText(_("px"))
|
||||
self.file_scale_up.setText(_("Don\'t enlarge"))
|
||||
self.file_scale_up.setText(_("Enlarge"))
|
||||
self.converting.setTitle(_("Convert images to the given format"))
|
||||
self.convert_tags.setTitle(_("Convert images saved to tags"))
|
||||
self.convert_tags_label.setText(_("New format:"))
|
||||
|
||||
@@ -27,6 +27,7 @@ from picard.config import get_config
|
||||
from picard.const.cover_processing import (
|
||||
COVER_CONVERTING_FORMATS,
|
||||
COVER_RESIZE_MODES,
|
||||
ResizeModes,
|
||||
)
|
||||
from picard.extension_points.options_pages import register_options_page
|
||||
from picard.i18n import (
|
||||
@@ -54,20 +55,16 @@ class CoverProcessingOptionsPage(OptionsPage):
|
||||
self.register_setting('filter_cover_by_size')
|
||||
self.register_setting('cover_minimum_width')
|
||||
self.register_setting('cover_minimum_height')
|
||||
self.register_setting('cover_tags_dont_enlarge')
|
||||
self.register_setting('cover_tags_enlarge')
|
||||
self.register_setting('cover_tags_resize')
|
||||
self.register_setting('cover_tags_resize_use_width')
|
||||
self.register_setting('cover_tags_resize_target_width')
|
||||
self.register_setting('cover_tags_resize_use_height')
|
||||
self.register_setting('cover_tags_resize_target_height')
|
||||
self.register_setting('cover_tags_resize_mode')
|
||||
self.register_setting('cover_tags_convert_images')
|
||||
self.register_setting('cover_tags_convert_to_format')
|
||||
self.register_setting('cover_file_dont_enlarge')
|
||||
self.register_setting('cover_file_enlarge')
|
||||
self.register_setting('cover_file_resize')
|
||||
self.register_setting('cover_file_resize_use_width')
|
||||
self.register_setting('cover_file_resize_target_width')
|
||||
self.register_setting('cover_file_resize_use_height')
|
||||
self.register_setting('cover_file_resize_target_height')
|
||||
self.register_setting('cover_file_resize_mode')
|
||||
self.register_setting('cover_file_convert_images')
|
||||
@@ -86,55 +83,47 @@ class CoverProcessingOptionsPage(OptionsPage):
|
||||
self.ui.convert_tags_format.addItems(COVER_CONVERTING_FORMATS)
|
||||
self.ui.convert_file_format.addItems(COVER_CONVERTING_FORMATS)
|
||||
|
||||
tags_checkboxes = (self.ui.tags_resize_width_label, self.ui.tags_resize_height_label)
|
||||
tags_at_least_one_checked = partial(self._ensure_at_least_one_checked, tags_checkboxes)
|
||||
for checkbox in tags_checkboxes:
|
||||
checkbox.clicked.connect(tags_at_least_one_checked)
|
||||
file_checkboxes = (self.ui.file_resize_width_label, self.ui.file_resize_height_label)
|
||||
file_at_least_one_checked = partial(self._ensure_at_least_one_checked, file_checkboxes)
|
||||
for checkbox in file_checkboxes:
|
||||
checkbox.clicked.connect(file_at_least_one_checked)
|
||||
tags_resize_mode_changed = partial(
|
||||
self._resize_mode_changed,
|
||||
self.ui.tags_resize_width_widget,
|
||||
self.ui.tags_resize_height_widget
|
||||
)
|
||||
file_resize_mode_changed = partial(
|
||||
self._resize_mode_changed,
|
||||
self.ui.file_resize_width_widget,
|
||||
self.ui.file_resize_height_widget
|
||||
)
|
||||
self.ui.tags_resize_mode.currentIndexChanged.connect(tags_resize_mode_changed)
|
||||
self.ui.file_resize_mode.currentIndexChanged.connect(file_resize_mode_changed)
|
||||
|
||||
self._spinboxes = {
|
||||
self.ui.tags_resize_width_label: self.ui.tags_resize_width_value,
|
||||
self.ui.tags_resize_height_label: self.ui.tags_resize_height_value,
|
||||
self.ui.file_resize_width_label: self.ui.file_resize_width_value,
|
||||
self.ui.file_resize_height_label: self.ui.file_resize_height_value,
|
||||
}
|
||||
for checkbox, spinbox in self._spinboxes.items():
|
||||
spinbox.setEnabled(checkbox.isChecked())
|
||||
checkbox.stateChanged.connect(self._update_resize_spinboxes)
|
||||
|
||||
def _update_resize_spinboxes(self):
|
||||
spinbox = self._spinboxes[self.sender()]
|
||||
spinbox.setEnabled(self.sender().isChecked())
|
||||
|
||||
def _ensure_at_least_one_checked(self, checkboxes, clicked):
|
||||
if not clicked and not any(checkbox.isChecked() for checkbox in checkboxes):
|
||||
sender = self.sender()
|
||||
sender.setChecked(True)
|
||||
def _resize_mode_changed(self, width_widget, height_widget, index):
|
||||
if index == ResizeModes.SCALE_TO_WIDTH:
|
||||
width_widget.setEnabled(True)
|
||||
height_widget.setEnabled(False)
|
||||
elif index == ResizeModes.SCALE_TO_HEIGHT:
|
||||
width_widget.setEnabled(False)
|
||||
height_widget.setEnabled(True)
|
||||
else:
|
||||
width_widget.setEnabled(True)
|
||||
height_widget.setEnabled(True)
|
||||
|
||||
def load(self):
|
||||
config = get_config()
|
||||
self.ui.filtering.setChecked(config.setting['filter_cover_by_size'])
|
||||
self.ui.filtering_width_value.setValue(config.setting['cover_minimum_width'])
|
||||
self.ui.filtering_height_value.setValue(config.setting['cover_minimum_height'])
|
||||
self.ui.tags_scale_up.setChecked(config.setting['cover_tags_dont_enlarge'])
|
||||
self.ui.tags_scale_up.setChecked(config.setting['cover_tags_enlarge'])
|
||||
self.ui.tags_scale_down.setChecked(config.setting['cover_tags_resize'])
|
||||
self.ui.tags_resize_width_label.setChecked(config.setting['cover_tags_resize_use_width'])
|
||||
self.ui.tags_resize_width_value.setValue(config.setting['cover_tags_resize_target_width'])
|
||||
self.ui.tags_resize_height_label.setChecked(config.setting['cover_tags_resize_use_height'])
|
||||
self.ui.tags_resize_height_value.setValue(config.setting['cover_tags_resize_target_height'])
|
||||
self.ui.tags_resize_mode.setCurrentIndex(self.mode_number_to_line[config.setting['cover_tags_resize_mode']]
|
||||
if config.setting['cover_tags_resize_mode'] in self.mode_number_to_line
|
||||
else 0)
|
||||
self.ui.convert_tags.setChecked(config.setting['cover_tags_convert_images'])
|
||||
self.ui.convert_tags_format.setCurrentText(config.setting['cover_tags_convert_to_format'])
|
||||
self.ui.file_scale_up.setChecked(config.setting['cover_file_dont_enlarge'])
|
||||
self.ui.file_scale_up.setChecked(config.setting['cover_file_enlarge'])
|
||||
self.ui.file_scale_down.setChecked(config.setting['cover_file_resize'])
|
||||
self.ui.file_resize_width_label.setChecked(config.setting['cover_file_resize_use_width'])
|
||||
self.ui.file_resize_width_value.setValue(config.setting['cover_file_resize_target_width'])
|
||||
self.ui.file_resize_height_label.setChecked(config.setting['cover_file_resize_use_height'])
|
||||
self.ui.file_resize_height_value.setValue(config.setting['cover_file_resize_target_height'])
|
||||
self.ui.file_resize_mode.setCurrentIndex(self.mode_number_to_line[config.setting['cover_file_resize_mode']]
|
||||
if config.setting['cover_file_resize_mode'] in self.mode_number_to_line
|
||||
@@ -147,20 +136,16 @@ class CoverProcessingOptionsPage(OptionsPage):
|
||||
config.setting['filter_cover_by_size'] = self.ui.filtering.isChecked()
|
||||
config.setting['cover_minimum_width'] = self.ui.filtering_width_value.value()
|
||||
config.setting['cover_minimum_height'] = self.ui.filtering_height_value.value()
|
||||
config.setting['cover_tags_dont_enlarge'] = self.ui.tags_scale_up.isChecked()
|
||||
config.setting['cover_tags_enlarge'] = self.ui.tags_scale_up.isChecked()
|
||||
config.setting['cover_tags_resize'] = self.ui.tags_scale_down.isChecked()
|
||||
config.setting['cover_tags_resize_use_width'] = self.ui.tags_resize_width_label.isChecked()
|
||||
config.setting['cover_tags_resize_target_width'] = self.ui.tags_resize_width_value.value()
|
||||
config.setting['cover_tags_resize_use_height'] = self.ui.tags_resize_height_label.isChecked()
|
||||
config.setting['cover_tags_resize_target_height'] = self.ui.tags_resize_height_value.value()
|
||||
config.setting['cover_tags_resize_mode'] = self.mode_line_to_number[self.ui.tags_resize_mode.currentIndex()]
|
||||
config.setting['cover_tags_convert_images'] = self.ui.convert_tags.isChecked()
|
||||
config.setting['cover_tags_convert_to_format'] = self.ui.convert_tags_format.currentText()
|
||||
config.setting['cover_file_dont_enlarge'] = self.ui.file_scale_up.isChecked()
|
||||
config.setting['cover_file_enlarge'] = self.ui.file_scale_up.isChecked()
|
||||
config.setting['cover_file_resize'] = self.ui.file_scale_down.isChecked()
|
||||
config.setting['cover_file_resize_use_width'] = self.ui.file_resize_width_label.isChecked()
|
||||
config.setting['cover_file_resize_target_width'] = self.ui.file_resize_width_value.value()
|
||||
config.setting['cover_file_resize_use_height'] = self.ui.file_resize_height_label.isChecked()
|
||||
config.setting['cover_file_resize_target_height'] = self.ui.file_resize_height_value.value()
|
||||
config.setting['cover_file_resize_mode'] = self.mode_line_to_number[self.ui.file_resize_mode.currentIndex()]
|
||||
config.setting['cover_file_convert_images'] = self.ui.convert_file.isChecked()
|
||||
|
||||
@@ -26,6 +26,7 @@ from PyQt6.QtGui import QImage
|
||||
from test.picardtestcase import PicardTestCase
|
||||
|
||||
from picard import config
|
||||
from picard.const.cover_processing import ResizeModes
|
||||
from picard.coverart.image import CoverArtImage
|
||||
from picard.coverart.processing import run_image_processors
|
||||
from picard.coverart.processing.filters import (
|
||||
@@ -85,21 +86,17 @@ class ImageProcessorsTest(PicardTestCase):
|
||||
self.settings = {
|
||||
'enabled_plugins': [],
|
||||
'cover_tags_resize': True,
|
||||
'cover_tags_dont_enlarge': False,
|
||||
'cover_tags_resize_use_width': True,
|
||||
'cover_tags_enlarge': True,
|
||||
'cover_tags_resize_target_width': 500,
|
||||
'cover_tags_resize_use_height': True,
|
||||
'cover_tags_resize_target_height': 500,
|
||||
'cover_tags_resize_mode': 0,
|
||||
'cover_tags_resize_mode': ResizeModes.MAINTAIN_ASPECT_RATIO,
|
||||
'cover_tags_convert_images': False,
|
||||
'cover_tags_convert_to_format': 'jpeg',
|
||||
'cover_file_resize': True,
|
||||
'cover_file_dont_enlarge': False,
|
||||
'cover_file_resize_use_width': True,
|
||||
'cover_file_enlarge': True,
|
||||
'cover_file_resize_target_width': 750,
|
||||
'cover_file_resize_use_height': True,
|
||||
'cover_file_resize_target_height': 750,
|
||||
'cover_file_resize_mode': 0,
|
||||
'cover_file_resize_mode': ResizeModes.MAINTAIN_ASPECT_RATIO,
|
||||
'save_images_to_tags': True,
|
||||
'save_images_to_files': True,
|
||||
'cover_file_convert_images': False,
|
||||
@@ -173,7 +170,7 @@ class ImageProcessorsTest(PicardTestCase):
|
||||
|
||||
def test_scale_down_only_width(self):
|
||||
settings = copy(self.settings)
|
||||
settings['cover_tags_resize_use_height'] = False
|
||||
settings['cover_tags_resize_mode'] = ResizeModes.SCALE_TO_WIDTH
|
||||
self.set_config_values(settings)
|
||||
self._check_resize_image((1000, 1000), (500, 500))
|
||||
self._check_resize_image((1000, 500), (500, 250))
|
||||
@@ -182,7 +179,7 @@ class ImageProcessorsTest(PicardTestCase):
|
||||
|
||||
def test_scale_down_only_height(self):
|
||||
settings = copy(self.settings)
|
||||
settings['cover_tags_resize_use_width'] = False
|
||||
settings['cover_tags_resize_mode'] = ResizeModes.SCALE_TO_HEIGHT
|
||||
self.set_config_values(settings)
|
||||
self._check_resize_image((1000, 1000), (500, 500))
|
||||
self._check_resize_image((1000, 500), (1000, 500))
|
||||
@@ -197,7 +194,7 @@ class ImageProcessorsTest(PicardTestCase):
|
||||
|
||||
def test_scale_up_only_width(self):
|
||||
settings = copy(self.settings)
|
||||
settings['cover_tags_resize_use_height'] = False
|
||||
settings['cover_tags_resize_mode'] = ResizeModes.SCALE_TO_WIDTH
|
||||
self.set_config_values(settings)
|
||||
self._check_resize_image((250, 250), (500, 500))
|
||||
self._check_resize_image((400, 500), (500, 625))
|
||||
@@ -206,7 +203,7 @@ class ImageProcessorsTest(PicardTestCase):
|
||||
|
||||
def test_scale_up_only_height(self):
|
||||
settings = copy(self.settings)
|
||||
settings['cover_tags_resize_use_width'] = False
|
||||
settings['cover_tags_resize_mode'] = ResizeModes.SCALE_TO_HEIGHT
|
||||
self.set_config_values(settings)
|
||||
self._check_resize_image((250, 250), (500, 500))
|
||||
self._check_resize_image((400, 500), (400, 500))
|
||||
@@ -223,62 +220,22 @@ class ImageProcessorsTest(PicardTestCase):
|
||||
|
||||
def test_stretch_both_dimensions(self):
|
||||
settings = copy(self.settings)
|
||||
settings['cover_tags_resize_mode'] = 2
|
||||
settings['cover_tags_resize_mode'] = ResizeModes.STRETCH_TO_FIT
|
||||
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_resize_mode'] = 2
|
||||
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_resize_mode'] = 2
|
||||
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_resize_mode'] = 1
|
||||
settings['cover_tags_resize_mode'] = ResizeModes.CROP_TO_FIT
|
||||
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_resize_mode'] = 1
|
||||
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_resize_mode'] = 1
|
||||
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 _check_convert_image(self, format, expected_format):
|
||||
image = ProcessingImage(create_fake_image(100, 100, format))
|
||||
processor = ConvertImage()
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>535</width>
|
||||
<height>467</height>
|
||||
<height>475</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
@@ -183,9 +183,9 @@
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="tags_resize_width_label">
|
||||
<widget class="QLabel" name="tags_resize_width_label">
|
||||
<property name="text">
|
||||
<string>Width:</string>
|
||||
<string>Maximum width:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -240,9 +240,9 @@
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="tags_resize_height_label">
|
||||
<widget class="QLabel" name="tags_resize_height_label">
|
||||
<property name="text">
|
||||
<string>Height:</string>
|
||||
<string>Maximum height:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -281,7 +281,7 @@
|
||||
<item>
|
||||
<widget class="QCheckBox" name="tags_scale_up">
|
||||
<property name="text">
|
||||
<string>Don't enlarge</string>
|
||||
<string>Enlarge</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -337,9 +337,9 @@
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="file_resize_width_label">
|
||||
<widget class="QLabel" name="file_resize_width_label">
|
||||
<property name="text">
|
||||
<string>Width:</string>
|
||||
<string>Maximum width:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -394,9 +394,9 @@
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="file_resize_height_label">
|
||||
<widget class="QLabel" name="file_resize_height_label">
|
||||
<property name="text">
|
||||
<string>Height:</string>
|
||||
<string>Maximum height:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -435,7 +435,7 @@
|
||||
<item>
|
||||
<widget class="QCheckBox" name="file_scale_up">
|
||||
<property name="text">
|
||||
<string>Don't enlarge</string>
|
||||
<string>Enlarge</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
||||
Reference in New Issue
Block a user