Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add more options to image resizing #2515

Merged
merged 7 commits into from
Jun 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 68 additions & 12 deletions picard/coverart/processing/processors.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,31 +35,87 @@ class ResizeImage(ImageProcessor):

def save_to_file(self):
config = get_config()
return config.setting['resize_images_saved_to_file']
return config.setting['cover_file_scale_down'] or config.setting['cover_file_scale_up']

def save_to_tags(self):
config = get_config()
return config.setting['resize_images_saved_to_tags']
return config.setting['cover_tags_scale_down'] or config.setting['cover_tags_scale_up']

def same_processing(self):
config = get_config()
same_width = config.setting['cover_tags_maximum_width'] == config.setting['cover_file_maximum_width']
same_height = config.setting['cover_tags_maximum_height'] == config.setting['cover_file_maximum_height']
return self.save_to_tags and self.save_to_file and same_width and same_height
setting = get_config().setting
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
tags_direction = (setting['cover_tags_scale_up'], setting['cover_tags_scale_down'])
file_direction = (setting['cover_file_scale_up'], setting['cover_file_scale_down'])
same_direction = tags_direction == file_direction and any(tags_direction)
tags_resize_mode = (setting['cover_tags_stretch'], setting['cover_tags_crop'])
file_resize_mode = (setting['cover_file_stretch'], setting['cover_file_crop'])
same_resize_mode = tags_resize_mode == file_resize_mode
return same_size and same_direction and same_resize_mode

def run(self, image, target):
start_time = time.time()
config = get_config()
if target == ProcessingTarget.TAGS:
max_width = config.setting['cover_tags_maximum_width']
max_height = config.setting['cover_tags_maximum_height']
scale_up = config.setting['cover_tags_scale_up']
scale_down = config.setting['cover_tags_scale_down']
use_width = config.setting['cover_tags_resize_use_width']
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']
stretch = config.setting["cover_tags_stretch"]
crop = config.setting["cover_tags_crop"]
else:
max_width = config.setting['cover_file_maximum_width']
max_height = config.setting['cover_file_maximum_height']
if image.info.width <= max_width and image.info.height <= max_height:
scale_up = config.setting['cover_file_scale_up']
scale_down = config.setting['cover_file_scale_down']
use_width = config.setting['cover_file_resize_use_width']
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']
stretch = config.setting["cover_file_stretch"]
crop = config.setting["cover_file_crop"]

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)
or ((width_scale_factor < 1 or height_scale_factor < 1) and not scale_down)):
# no resizing needed
return

qimage = image.get_result()
scaled_image = qimage.scaled(max_width, max_height, Qt.AspectRatioMode.KeepAspectRatio)
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)

log.debug(
"Resized cover art from %d x %d to %d x %d in %.2f ms",
image.info.width,
Expand Down
2 changes: 1 addition & 1 deletion picard/extension_points/cover_art_processors.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ def save_to_file(self):
def same_processing(self):
return False

def run(self, data, target):
def run(self, image, target):
pass


Expand Down
22 changes: 16 additions & 6 deletions picard/options.py
Original file line number Diff line number Diff line change
Expand Up @@ -175,12 +175,22 @@
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', 'resize_images_saved_to_tags', False)
IntOption('setting', 'cover_tags_maximum_width', DEFAULT_COVER_MAX_SIZE)
IntOption('setting', 'cover_tags_maximum_height', DEFAULT_COVER_MAX_SIZE)
BoolOption('setting', 'resize_images_saved_to_file', False)
IntOption('setting', 'cover_file_maximum_width', DEFAULT_COVER_MAX_SIZE)
IntOption('setting', 'cover_file_maximum_height', DEFAULT_COVER_MAX_SIZE)
BoolOption('setting', 'cover_tags_scale_up', False)
BoolOption('setting', 'cover_tags_scale_down', 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)
BoolOption('setting', 'cover_tags_stretch', False)
BoolOption('setting', 'cover_tags_crop', False)
BoolOption('setting', 'cover_file_scale_up', False)
BoolOption('setting', 'cover_file_scale_down', 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)
BoolOption('setting', 'cover_file_stretch', False)
BoolOption('setting', 'cover_file_crop', False)

# picard/ui/options/dialog.py
# Attached Profiles
Expand Down
Loading
Loading